[{"data":1,"prerenderedAt":3978},["ShallowReactive",2],{"/en-us/blog/tags/devsecops/":3,"navigation-en-us":20,"banner-en-us":450,"footer-en-us":467,"DevSecOps-tag-page-en-us":677},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"content":8,"config":11,"_id":13,"_type":14,"title":15,"_source":16,"_file":17,"_stem":18,"_extension":19},"/en-us/blog/tags/devsecops","tags",false,"",{"tag":9,"tagSlug":10},"DevSecOps","devsecops",{"template":12},"BlogTag","content:en-us:blog:tags:devsecops.yml","yaml","Devsecops","content","en-us/blog/tags/devsecops.yml","en-us/blog/tags/devsecops","yml",{"_path":21,"_dir":22,"_draft":6,"_partial":6,"_locale":7,"data":23,"_id":446,"_type":14,"title":447,"_source":16,"_file":448,"_stem":449,"_extension":19},"/shared/en-us/main-navigation","en-us",{"logo":24,"freeTrial":29,"sales":34,"login":39,"items":44,"search":377,"minimal":408,"duo":427,"pricingDeployment":436},{"config":25},{"href":26,"dataGaName":27,"dataGaLocation":28},"/","gitlab logo","header",{"text":30,"config":31},"Get free trial",{"href":32,"dataGaName":33,"dataGaLocation":28},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":35,"config":36},"Talk to sales",{"href":37,"dataGaName":38,"dataGaLocation":28},"/sales/","sales",{"text":40,"config":41},"Sign in",{"href":42,"dataGaName":43,"dataGaLocation":28},"https://gitlab.com/users/sign_in/","sign in",[45,89,187,192,298,358],{"text":46,"config":47,"cards":49,"footer":72},"Platform",{"dataNavLevelOne":48},"platform",[50,56,64],{"title":46,"description":51,"link":52},"The most comprehensive AI-powered DevSecOps Platform",{"text":53,"config":54},"Explore our Platform",{"href":55,"dataGaName":48,"dataGaLocation":28},"/platform/",{"title":57,"description":58,"link":59},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":60,"config":61},"Meet GitLab Duo",{"href":62,"dataGaName":63,"dataGaLocation":28},"/gitlab-duo/","gitlab duo ai",{"title":65,"description":66,"link":67},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":68,"config":69},"Learn more",{"href":70,"dataGaName":71,"dataGaLocation":28},"/why-gitlab/","why gitlab",{"title":73,"items":74},"Get started with",[75,80,85],{"text":76,"config":77},"Platform Engineering",{"href":78,"dataGaName":79,"dataGaLocation":28},"/solutions/platform-engineering/","platform engineering",{"text":81,"config":82},"Developer Experience",{"href":83,"dataGaName":84,"dataGaLocation":28},"/developer-experience/","Developer experience",{"text":86,"config":87},"MLOps",{"href":88,"dataGaName":86,"dataGaLocation":28},"/topics/devops/the-role-of-ai-in-devops/",{"text":90,"left":91,"config":92,"link":94,"lists":98,"footer":169},"Product",true,{"dataNavLevelOne":93},"solutions",{"text":95,"config":96},"View all Solutions",{"href":97,"dataGaName":93,"dataGaLocation":28},"/solutions/",[99,124,148],{"title":100,"description":101,"link":102,"items":107},"Automation","CI/CD and automation to accelerate deployment",{"config":103},{"icon":104,"href":105,"dataGaName":106,"dataGaLocation":28},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[108,112,116,120],{"text":109,"config":110},"CI/CD",{"href":111,"dataGaLocation":28,"dataGaName":109},"/solutions/continuous-integration/",{"text":113,"config":114},"AI-Assisted Development",{"href":62,"dataGaLocation":28,"dataGaName":115},"AI assisted development",{"text":117,"config":118},"Source Code Management",{"href":119,"dataGaLocation":28,"dataGaName":117},"/solutions/source-code-management/",{"text":121,"config":122},"Automated Software Delivery",{"href":105,"dataGaLocation":28,"dataGaName":123},"Automated software delivery",{"title":125,"description":126,"link":127,"items":132},"Security","Deliver code faster without compromising security",{"config":128},{"href":129,"dataGaName":130,"dataGaLocation":28,"icon":131},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[133,138,143],{"text":134,"config":135},"Application Security Testing",{"href":136,"dataGaName":137,"dataGaLocation":28},"/solutions/application-security-testing/","Application security testing",{"text":139,"config":140},"Software Supply Chain Security",{"href":141,"dataGaLocation":28,"dataGaName":142},"/solutions/supply-chain/","Software supply chain security",{"text":144,"config":145},"Software Compliance",{"href":146,"dataGaName":147,"dataGaLocation":28},"/solutions/software-compliance/","software compliance",{"title":149,"link":150,"items":155},"Measurement",{"config":151},{"icon":152,"href":153,"dataGaName":154,"dataGaLocation":28},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[156,160,164],{"text":157,"config":158},"Visibility & Measurement",{"href":153,"dataGaLocation":28,"dataGaName":159},"Visibility and Measurement",{"text":161,"config":162},"Value Stream Management",{"href":163,"dataGaLocation":28,"dataGaName":161},"/solutions/value-stream-management/",{"text":165,"config":166},"Analytics & Insights",{"href":167,"dataGaLocation":28,"dataGaName":168},"/solutions/analytics-and-insights/","Analytics and insights",{"title":170,"items":171},"GitLab for",[172,177,182],{"text":173,"config":174},"Enterprise",{"href":175,"dataGaLocation":28,"dataGaName":176},"/enterprise/","enterprise",{"text":178,"config":179},"Small Business",{"href":180,"dataGaLocation":28,"dataGaName":181},"/small-business/","small business",{"text":183,"config":184},"Public Sector",{"href":185,"dataGaLocation":28,"dataGaName":186},"/solutions/public-sector/","public sector",{"text":188,"config":189},"Pricing",{"href":190,"dataGaName":191,"dataGaLocation":28,"dataNavLevelOne":191},"/pricing/","pricing",{"text":193,"config":194,"link":196,"lists":200,"feature":285},"Resources",{"dataNavLevelOne":195},"resources",{"text":197,"config":198},"View all resources",{"href":199,"dataGaName":195,"dataGaLocation":28},"/resources/",[201,234,257],{"title":202,"items":203},"Getting started",[204,209,214,219,224,229],{"text":205,"config":206},"Install",{"href":207,"dataGaName":208,"dataGaLocation":28},"/install/","install",{"text":210,"config":211},"Quick start guides",{"href":212,"dataGaName":213,"dataGaLocation":28},"/get-started/","quick setup checklists",{"text":215,"config":216},"Learn",{"href":217,"dataGaLocation":28,"dataGaName":218},"https://university.gitlab.com/","learn",{"text":220,"config":221},"Product documentation",{"href":222,"dataGaName":223,"dataGaLocation":28},"https://docs.gitlab.com/","product documentation",{"text":225,"config":226},"Best practice videos",{"href":227,"dataGaName":228,"dataGaLocation":28},"/getting-started-videos/","best practice videos",{"text":230,"config":231},"Integrations",{"href":232,"dataGaName":233,"dataGaLocation":28},"/integrations/","integrations",{"title":235,"items":236},"Discover",[237,242,247,252],{"text":238,"config":239},"Customer success stories",{"href":240,"dataGaName":241,"dataGaLocation":28},"/customers/","customer success stories",{"text":243,"config":244},"Blog",{"href":245,"dataGaName":246,"dataGaLocation":28},"/blog/","blog",{"text":248,"config":249},"Remote",{"href":250,"dataGaName":251,"dataGaLocation":28},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":253,"config":254},"TeamOps",{"href":255,"dataGaName":256,"dataGaLocation":28},"/teamops/","teamops",{"title":258,"items":259},"Connect",[260,265,270,275,280],{"text":261,"config":262},"GitLab Services",{"href":263,"dataGaName":264,"dataGaLocation":28},"/services/","services",{"text":266,"config":267},"Community",{"href":268,"dataGaName":269,"dataGaLocation":28},"/community/","community",{"text":271,"config":272},"Forum",{"href":273,"dataGaName":274,"dataGaLocation":28},"https://forum.gitlab.com/","forum",{"text":276,"config":277},"Events",{"href":278,"dataGaName":279,"dataGaLocation":28},"/events/","events",{"text":281,"config":282},"Partners",{"href":283,"dataGaName":284,"dataGaLocation":28},"/partners/","partners",{"backgroundColor":286,"textColor":287,"text":288,"image":289,"link":293},"#2f2a6b","#fff","Insights for the future of software development",{"altText":290,"config":291},"the source promo card",{"src":292},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":294,"config":295},"Read the latest",{"href":296,"dataGaName":297,"dataGaLocation":28},"/the-source/","the source",{"text":299,"config":300,"lists":302},"Company",{"dataNavLevelOne":301},"company",[303],{"items":304},[305,310,316,318,323,328,333,338,343,348,353],{"text":306,"config":307},"About",{"href":308,"dataGaName":309,"dataGaLocation":28},"/company/","about",{"text":311,"config":312,"footerGa":315},"Jobs",{"href":313,"dataGaName":314,"dataGaLocation":28},"/jobs/","jobs",{"dataGaName":314},{"text":276,"config":317},{"href":278,"dataGaName":279,"dataGaLocation":28},{"text":319,"config":320},"Leadership",{"href":321,"dataGaName":322,"dataGaLocation":28},"/company/team/e-group/","leadership",{"text":324,"config":325},"Team",{"href":326,"dataGaName":327,"dataGaLocation":28},"/company/team/","team",{"text":329,"config":330},"Handbook",{"href":331,"dataGaName":332,"dataGaLocation":28},"https://handbook.gitlab.com/","handbook",{"text":334,"config":335},"Investor relations",{"href":336,"dataGaName":337,"dataGaLocation":28},"https://ir.gitlab.com/","investor relations",{"text":339,"config":340},"Trust Center",{"href":341,"dataGaName":342,"dataGaLocation":28},"/security/","trust center",{"text":344,"config":345},"AI Transparency Center",{"href":346,"dataGaName":347,"dataGaLocation":28},"/ai-transparency-center/","ai transparency center",{"text":349,"config":350},"Newsletter",{"href":351,"dataGaName":352,"dataGaLocation":28},"/company/contact/","newsletter",{"text":354,"config":355},"Press",{"href":356,"dataGaName":357,"dataGaLocation":28},"/press/","press",{"text":359,"config":360,"lists":361},"Contact us",{"dataNavLevelOne":301},[362],{"items":363},[364,367,372],{"text":35,"config":365},{"href":37,"dataGaName":366,"dataGaLocation":28},"talk to sales",{"text":368,"config":369},"Get help",{"href":370,"dataGaName":371,"dataGaLocation":28},"/support/","get help",{"text":373,"config":374},"Customer portal",{"href":375,"dataGaName":376,"dataGaLocation":28},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":378,"login":379,"suggestions":386},"Close",{"text":380,"link":381},"To search repositories and projects, login to",{"text":382,"config":383},"gitlab.com",{"href":42,"dataGaName":384,"dataGaLocation":385},"search login","search",{"text":387,"default":388},"Suggestions",[389,391,395,397,401,405],{"text":57,"config":390},{"href":62,"dataGaName":57,"dataGaLocation":385},{"text":392,"config":393},"Code Suggestions (AI)",{"href":394,"dataGaName":392,"dataGaLocation":385},"/solutions/code-suggestions/",{"text":109,"config":396},{"href":111,"dataGaName":109,"dataGaLocation":385},{"text":398,"config":399},"GitLab on AWS",{"href":400,"dataGaName":398,"dataGaLocation":385},"/partners/technology-partners/aws/",{"text":402,"config":403},"GitLab on Google Cloud",{"href":404,"dataGaName":402,"dataGaLocation":385},"/partners/technology-partners/google-cloud-platform/",{"text":406,"config":407},"Why GitLab?",{"href":70,"dataGaName":406,"dataGaLocation":385},{"freeTrial":409,"mobileIcon":414,"desktopIcon":419,"secondaryButton":422},{"text":410,"config":411},"Start free trial",{"href":412,"dataGaName":33,"dataGaLocation":413},"https://gitlab.com/-/trials/new/","nav",{"altText":415,"config":416},"Gitlab Icon",{"src":417,"dataGaName":418,"dataGaLocation":413},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":415,"config":420},{"src":421,"dataGaName":418,"dataGaLocation":413},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":423,"config":424},"Get Started",{"href":425,"dataGaName":426,"dataGaLocation":413},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":428,"mobileIcon":432,"desktopIcon":434},{"text":429,"config":430},"Learn more about GitLab Duo",{"href":62,"dataGaName":431,"dataGaLocation":413},"gitlab duo",{"altText":415,"config":433},{"src":417,"dataGaName":418,"dataGaLocation":413},{"altText":415,"config":435},{"src":421,"dataGaName":418,"dataGaLocation":413},{"freeTrial":437,"mobileIcon":442,"desktopIcon":444},{"text":438,"config":439},"Back to pricing",{"href":190,"dataGaName":440,"dataGaLocation":413,"icon":441},"back to pricing","GoBack",{"altText":415,"config":443},{"src":417,"dataGaName":418,"dataGaLocation":413},{"altText":415,"config":445},{"src":421,"dataGaName":418,"dataGaLocation":413},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":451,"_dir":22,"_draft":6,"_partial":6,"_locale":7,"title":452,"button":453,"image":458,"config":462,"_id":464,"_type":14,"_source":16,"_file":465,"_stem":466,"_extension":19},"/shared/en-us/banner","is now in public beta!",{"text":454,"config":455},"Try the Beta",{"href":456,"dataGaName":457,"dataGaLocation":28},"/gitlab-duo/agent-platform/","duo banner",{"altText":459,"config":460},"GitLab Duo Agent Platform",{"src":461},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":463},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":468,"_dir":22,"_draft":6,"_partial":6,"_locale":7,"data":469,"_id":673,"_type":14,"title":674,"_source":16,"_file":675,"_stem":676,"_extension":19},"/shared/en-us/main-footer",{"text":470,"source":471,"edit":477,"contribute":482,"config":487,"items":492,"minimal":665},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":472,"config":473},"View page source",{"href":474,"dataGaName":475,"dataGaLocation":476},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":478,"config":479},"Edit this page",{"href":480,"dataGaName":481,"dataGaLocation":476},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":483,"config":484},"Please contribute",{"href":485,"dataGaName":486,"dataGaLocation":476},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":488,"facebook":489,"youtube":490,"linkedin":491},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[493,516,572,601,635],{"title":46,"links":494,"subMenu":499},[495],{"text":496,"config":497},"DevSecOps platform",{"href":55,"dataGaName":498,"dataGaLocation":476},"devsecops platform",[500],{"title":188,"links":501},[502,506,511],{"text":503,"config":504},"View plans",{"href":190,"dataGaName":505,"dataGaLocation":476},"view plans",{"text":507,"config":508},"Why Premium?",{"href":509,"dataGaName":510,"dataGaLocation":476},"/pricing/premium/","why premium",{"text":512,"config":513},"Why Ultimate?",{"href":514,"dataGaName":515,"dataGaLocation":476},"/pricing/ultimate/","why ultimate",{"title":517,"links":518},"Solutions",[519,524,526,528,533,538,542,545,549,554,556,559,562,567],{"text":520,"config":521},"Digital transformation",{"href":522,"dataGaName":523,"dataGaLocation":476},"/topics/digital-transformation/","digital transformation",{"text":134,"config":525},{"href":136,"dataGaName":134,"dataGaLocation":476},{"text":123,"config":527},{"href":105,"dataGaName":106,"dataGaLocation":476},{"text":529,"config":530},"Agile development",{"href":531,"dataGaName":532,"dataGaLocation":476},"/solutions/agile-delivery/","agile delivery",{"text":534,"config":535},"Cloud transformation",{"href":536,"dataGaName":537,"dataGaLocation":476},"/topics/cloud-native/","cloud transformation",{"text":539,"config":540},"SCM",{"href":119,"dataGaName":541,"dataGaLocation":476},"source code management",{"text":109,"config":543},{"href":111,"dataGaName":544,"dataGaLocation":476},"continuous integration & delivery",{"text":546,"config":547},"Value stream management",{"href":163,"dataGaName":548,"dataGaLocation":476},"value stream management",{"text":550,"config":551},"GitOps",{"href":552,"dataGaName":553,"dataGaLocation":476},"/solutions/gitops/","gitops",{"text":173,"config":555},{"href":175,"dataGaName":176,"dataGaLocation":476},{"text":557,"config":558},"Small business",{"href":180,"dataGaName":181,"dataGaLocation":476},{"text":560,"config":561},"Public sector",{"href":185,"dataGaName":186,"dataGaLocation":476},{"text":563,"config":564},"Education",{"href":565,"dataGaName":566,"dataGaLocation":476},"/solutions/education/","education",{"text":568,"config":569},"Financial services",{"href":570,"dataGaName":571,"dataGaLocation":476},"/solutions/finance/","financial services",{"title":193,"links":573},[574,576,578,580,583,585,587,589,591,593,595,597,599],{"text":205,"config":575},{"href":207,"dataGaName":208,"dataGaLocation":476},{"text":210,"config":577},{"href":212,"dataGaName":213,"dataGaLocation":476},{"text":215,"config":579},{"href":217,"dataGaName":218,"dataGaLocation":476},{"text":220,"config":581},{"href":222,"dataGaName":582,"dataGaLocation":476},"docs",{"text":243,"config":584},{"href":245,"dataGaName":246,"dataGaLocation":476},{"text":238,"config":586},{"href":240,"dataGaName":241,"dataGaLocation":476},{"text":248,"config":588},{"href":250,"dataGaName":251,"dataGaLocation":476},{"text":261,"config":590},{"href":263,"dataGaName":264,"dataGaLocation":476},{"text":253,"config":592},{"href":255,"dataGaName":256,"dataGaLocation":476},{"text":266,"config":594},{"href":268,"dataGaName":269,"dataGaLocation":476},{"text":271,"config":596},{"href":273,"dataGaName":274,"dataGaLocation":476},{"text":276,"config":598},{"href":278,"dataGaName":279,"dataGaLocation":476},{"text":281,"config":600},{"href":283,"dataGaName":284,"dataGaLocation":476},{"title":299,"links":602},[603,605,607,609,611,613,615,619,624,626,628,630],{"text":306,"config":604},{"href":308,"dataGaName":301,"dataGaLocation":476},{"text":311,"config":606},{"href":313,"dataGaName":314,"dataGaLocation":476},{"text":319,"config":608},{"href":321,"dataGaName":322,"dataGaLocation":476},{"text":324,"config":610},{"href":326,"dataGaName":327,"dataGaLocation":476},{"text":329,"config":612},{"href":331,"dataGaName":332,"dataGaLocation":476},{"text":334,"config":614},{"href":336,"dataGaName":337,"dataGaLocation":476},{"text":616,"config":617},"Sustainability",{"href":618,"dataGaName":616,"dataGaLocation":476},"/sustainability/",{"text":620,"config":621},"Diversity, inclusion and belonging (DIB)",{"href":622,"dataGaName":623,"dataGaLocation":476},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":339,"config":625},{"href":341,"dataGaName":342,"dataGaLocation":476},{"text":349,"config":627},{"href":351,"dataGaName":352,"dataGaLocation":476},{"text":354,"config":629},{"href":356,"dataGaName":357,"dataGaLocation":476},{"text":631,"config":632},"Modern Slavery Transparency Statement",{"href":633,"dataGaName":634,"dataGaLocation":476},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":636,"links":637},"Contact Us",[638,641,643,645,650,655,660],{"text":639,"config":640},"Contact an expert",{"href":37,"dataGaName":38,"dataGaLocation":476},{"text":368,"config":642},{"href":370,"dataGaName":371,"dataGaLocation":476},{"text":373,"config":644},{"href":375,"dataGaName":376,"dataGaLocation":476},{"text":646,"config":647},"Status",{"href":648,"dataGaName":649,"dataGaLocation":476},"https://status.gitlab.com/","status",{"text":651,"config":652},"Terms of use",{"href":653,"dataGaName":654,"dataGaLocation":476},"/terms/","terms of use",{"text":656,"config":657},"Privacy statement",{"href":658,"dataGaName":659,"dataGaLocation":476},"/privacy/","privacy statement",{"text":661,"config":662},"Cookie preferences",{"dataGaName":663,"dataGaLocation":476,"id":664,"isOneTrustButton":91},"cookie preferences","ot-sdk-btn",{"items":666},[667,669,671],{"text":651,"config":668},{"href":653,"dataGaName":654,"dataGaLocation":476},{"text":656,"config":670},{"href":658,"dataGaName":659,"dataGaLocation":476},{"text":661,"config":672},{"dataGaName":663,"dataGaLocation":476,"id":664,"isOneTrustButton":91},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",{"allPosts":678,"featuredPost":3958,"totalPagesCount":3976,"initialPosts":3977},[679,703,726,746,768,789,810,834,855,875,896,917,937,960,981,1002,1023,1048,1069,1091,1111,1131,1149,1167,1185,1205,1225,1245,1266,1285,1306,1328,1347,1366,1384,1406,1425,1444,1465,1485,1506,1523,1544,1564,1583,1602,1622,1642,1661,1681,1700,1721,1741,1759,1779,1799,1818,1836,1855,1875,1896,1915,1933,1952,1970,1989,2009,2027,2047,2067,2086,2106,2128,2149,2168,2189,2207,2226,2244,2262,2280,2301,2320,2339,2357,2376,2395,2414,2433,2452,2471,2489,2510,2530,2548,2567,2587,2606,2626,2646,2664,2683,2702,2721,2739,2758,2777,2797,2817,2837,2857,2875,2894,2913,2932,2951,2969,2988,3006,3025,3047,3066,3085,3103,3122,3141,3161,3181,3201,3218,3237,3255,3275,3296,3314,3334,3354,3373,3391,3410,3428,3448,3466,3485,3503,3522,3541,3561,3579,3597,3619,3637,3657,3675,3693,3711,3730,3749,3769,3789,3808,3827,3847,3867,3886,3905,3926,3944],{"_path":680,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":681,"content":689,"config":696,"_id":699,"_type":14,"title":700,"_source":16,"_file":701,"_stem":702,"_extension":19},"/en-us/blog/3-tips-to-improve-your-security-risk-management-program",{"title":682,"description":683,"ogTitle":682,"ogDescription":683,"noIndex":6,"ogImage":684,"ogUrl":685,"ogSiteName":686,"ogType":687,"canonicalUrls":685,"schema":688},"3 tips to improve your security risk management program","Establishing a security risk management program is more than just checking the compliance box. Here are a few ways to help better protect information and support strategic decision-making.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665667/Blog/Hero%20Images/built-in-security.jpg","https://about.gitlab.com/blog/3-tips-to-improve-your-security-risk-management-program","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"3 tips to improve your security risk management program\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kyle Smith\"}],\n        \"datePublished\": \"2024-05-28\",\n      }",{"title":682,"description":683,"authors":690,"heroImage":684,"date":692,"body":693,"category":694,"tags":695},[691],"Kyle Smith","2024-05-28","Risk management is typically viewed as a check-the-box compliance activity. It can also be seen as a blocker. Effective risk management programs provide their company’s decision-makers with relevant, reliable, and usable information to support the achievement of objectives and mitigation of risks. [GitLab’s Security Operational Risk Management (StORM) program](https://handbook.gitlab.com/handbook/security/security-assurance/security-risk/storm-program/) identifies, monitors, and supports the remediation of security risks. Risk information from the StORM program informs our Security division’s strategy and helps to maintain the [confidentiality, integrity, and availability (CIA)](https://www.techtarget.com/whatis/definition/Confidentiality-integrity-and-availability-CIA) of customer and GitLab data. We’ve made some changes over the past year to our risk management practices to better support strategic decision-making and we’d like to share some of these changes in the spirit of [collaboration](https://handbook.gitlab.com/handbook/values/#collaboration) and [transparency](https://handbook.gitlab.com/handbook/values/#transparency).\n\n## Aggregate and self-serve risk information\nRisk information measures and contextualizes risks. For example, if we have a risk related to identity management, helpful risk information might be the number of open compliance observations related to identity management (for example, lack of multi-factor authentication for # applications). A more qualitative example for the same risk could be the latest developments related to the rollout of a single sign-on (SSO) platform. \n\nThe efficiency of self-serving risk information will depend on the level of access you have to company information. Aggregating risk information at GitLab involves searching the following sources (among others):\n\n- [GitLab](https://gitlab.com/) - GitLab objects (i.e., epics, issues, and merge requests) related to our risk\n- Google Drive - documents, spreadsheets, and presentations\n- Shared calendars - meetings, agendas, and recordings\n- Slack - recent announcements and discussions\n- [The GitLab Handbook](https://handbook.gitlab.com/handbook/) - policies, key contacts, operational guides, and roadmaps\n\nBy finding risk information ourselves, we get familiar with the risks, identify key team members, reduce the risk of bias, and save risk owners time. When pulling information from other teams/departments/functions that report on risks (for example, Internal Audit), highlight that overlap to show a more comprehensive view of your risks. In your search for risk information, try to find out if customers are interested in this risk and what competitors are doing about it? Linking disparate information in an easily consumable way also helps folks get up to speed quickly (very helpful for new team members).\n\n## Identify metrics to contextualize risks\n\nRisks can be ambiguous. Having metrics to help put them into context and measure progress toward a goal [is key to making better decisions](https://online.hbs.edu/blog/post/data-driven-decision-making). How are these risks affecting the achievement of objectives, what does success look like? Identify the end goal and how that can be measured. Even if the information for the metric isn’t readily available, it’s a helpful guide until you can establish the metric or activity that generates the metric. High-level metrics are also helpful to understand the breadth and complexity of your company such as number of:\n- team members\n- temporary service providers (i.e., contractors)\n- applications in your tech stack\n- production servers\n- active vendors\n- countries in which your company operates\n\nWhen documenting or presenting this information (ex., a [quarterly risk report](https://handbook.gitlab.com/handbook/security/security-assurance/security-risk/storm-program/#risk-tracking-and-reporting)), it’s [helpful to link](https://handbook.gitlab.com/handbook/communication/#cross-link) out to the source of these metrics so that they can be viewed by readers. Ask decision-makers for feedback on these metrics, asking, \"Is what we have helpful or is there anything else you'd like to see?\"\n\n## Open up access to risk information for greater awareness and engagement\n\nAccess to risk-related information, audit findings, and other compliance output is usually restricted to specific teams or select team members. Does it have to be? We’ve found that opening up access and hosting it on a familiar platform (GitLab for us) has increased engagement and awareness.\n\nRisks and objectives are always changing. Differing perspectives gained from greater transparency can help refine risks and create an environment for new ideas. Risks should be considered [always in draft](https://handbook.gitlab.com/handbook/values/#everything-is-in-draft) and contributions from risk owners and other contributors should be encouraged.\n\nHave you tried any of the above suggestions? If so, how did it go? Or do you have ideas about how we can better support security-related decision-making? We’d love to hear from you. Please [share feedback in our forum](https://forum.gitlab.com/t/3-tips-to-improve-your-security-risk-management-program/104994) or email us directly at `securityrisk@gitlab.com`.\n\nIf you’d like to learn more about how we manage security risk, please check out [the StORM program](https://handbook.gitlab.com/handbook/security/security-assurance/security-risk/storm-program/) in the GitLab Handbook.","security",[694,9],{"slug":697,"featured":91,"template":698},"3-tips-to-improve-your-security-risk-management-program","BlogPost","content:en-us:blog:3-tips-to-improve-your-security-risk-management-program.yml","3 Tips To Improve Your Security Risk Management Program","en-us/blog/3-tips-to-improve-your-security-risk-management-program.yml","en-us/blog/3-tips-to-improve-your-security-risk-management-program",{"_path":704,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":705,"content":711,"config":720,"_id":722,"_type":14,"title":723,"_source":16,"_file":724,"_stem":725,"_extension":19},"/en-us/blog/5-things-to-know-from-our-linkedin-live-security-deep-dive",{"title":706,"description":707,"ogTitle":706,"ogDescription":707,"noIndex":6,"ogImage":708,"ogUrl":709,"ogSiteName":686,"ogType":687,"canonicalUrls":709,"schema":710},"5 things to know from our LinkedIn Live Security Deep Dive","Security experts and product leaders offered their take on new developments in application security and the latest from GitLab 17.5.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659856/Blog/Hero%20Images/blog-hero-banner-1-0178-820x470-fy25.png","https://about.gitlab.com/blog/5-things-to-know-from-our-linkedin-live-security-deep-dive","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"5 things to know from our LinkedIn Live Security Deep Dive\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Fatima Sarah Khalid\"}],\n        \"datePublished\": \"2024-10-28\",\n      }",{"title":706,"description":707,"authors":712,"heroImage":708,"date":714,"body":715,"category":694,"tags":716},[713],"Fatima Sarah Khalid","2024-10-28","[GitLab's October LinkedIn Live broadcast](https://www.linkedin.com/feed/update/urn:li:activity:7255246777077936128) brought together security experts and product leaders to discuss the latest developments in application security and highlight key features from the GitLab 17.5 release. In case you missed it, here's what you need to know.\n\n## 1. Software is moving faster and security is struggling to keep up\nDevelopment teams are shipping at record speeds, but their security counterparts are finding it difficult to meet that pace. Our [DevSecOps survey](https://about.gitlab.com/developer-survey/) revealed that 66% of companies are shipping code twice as fast as last year, while 55% of security teams are finding vulnerabilities after code is merged to test environments. With 80% of top data breaches coming from application layer attacks, this gap must be addressed.\n\n\u003Cdiv style=\"padding:56.25% 0 0 0;position:relative;\">\u003Ciframe src=\"https://player.vimeo.com/video/1023367700?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" title=\"Market Insights\">\u003C/iframe>\u003C/div>\u003Cscript src=\"https://player.vimeo.com/api/player.js\">\u003C/script>\n\n## 2. Advanced SAST is getting smarter\nGitLab's new [Advanced SAST](https://about.gitlab.com/blog/gitlab-advanced-sast-is-now-generally-available/) capabilities are a game-changer for security testing. Built on technology acquired from Oxeye, Advanced SAST offers cross-file and cross-function scanning with taint analysis. The star feature is a code flow view that lets developers trace vulnerabilities from source to sink, making it easier to understand and fix security issues.\n\n\u003Cdiv style=\"padding:56.25% 0 0 0;position:relative;\">\u003Ciframe src=\"https://player.vimeo.com/video/1023369304?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" title=\"Advanced SAST\">\u003C/iframe>\u003C/div>\u003Cscript src=\"https://player.vimeo.com/api/player.js\">\u003C/script>\n\n> Learn even more with our [Advanced SAST tutorial](https://about.gitlab.com/blog/quick-vulnerability-remediation-with-gitlab-advanced-sast-duo-ai/).\n\n## 3. Accidental secret commits are a thing of the past\nGitLab's new [secret push protection feature](https://about.gitlab.com/blog/prevent-secret-leaks-in-source-code-with-gitlab-secret-push-protection/) stops sensitive information from reaching your GitLab repository by checking the contents of each commit. Instead of dealing with the aftermath of exposed credentials, the system catches secrets before they're committed, saving security teams countless hours of remediation work.\n\n\u003Cdiv style=\"padding:56.25% 0 0 0;position:relative;\">\u003Ciframe src=\"https://player.vimeo.com/video/1023370222?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" title=\"Secret Push\">\u003C/iframe>\u003C/div>\u003Cscript src=\"https://player.vimeo.com/api/player.js\">\u003C/script>\n\n## 4. AI is a security catalyst\nAI isn't just for code completion anymore. GitLab Duo has evolved to understand merge requests and provide contextual security assistance. With the new Quick Chat feature (accessible via Alt+C), developers can get security insights without leaving their editor.\n\n\u003Cdiv style=\"padding:56.25% 0 0 0;position:relative;\">\u003Ciframe src=\"https://player.vimeo.com/video/1023385333?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" title=\"AI Security\">\u003C/iframe>\u003C/div>\u003Cscript src=\"https://player.vimeo.com/api/player.js\">\u003C/script>\n\n## 5. Static reachability reduces security noise\nThe new static reachability feature for Python and Java helps teams focus on vulnerabilities that matter. By identifying which dependencies are actually used in your code, it reduces false positives and helps teams prioritize real security threats.\n\n\u003Cdiv style=\"padding:56.25% 0 0 0;position:relative;\">\u003Ciframe src=\"https://player.vimeo.com/video/1023388137?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" title=\"Static Reachability\">\u003C/iframe>\u003C/div>\u003Cscript src=\"https://player.vimeo.com/api/player.js\">\u003C/script>\n\n## Watch on-demand now\n\n[Watch the full \"Security Deep Dive\" recording](https://www.linkedin.com/feed/update/urn:li:activity:7255246777077936128) to see these features in action and hear more insights from our security experts.\n\nBe sure to follow GitLab on LinkedIn to be notified of our monthly broadcasts and get more insights and the latest news about AI-powered DevSecOps.",[717,694,718,9,719],"AI/ML","webcast","features",{"slug":721,"featured":91,"template":698},"5-things-to-know-from-our-linkedin-live-security-deep-dive","content:en-us:blog:5-things-to-know-from-our-linkedin-live-security-deep-dive.yml","5 Things To Know From Our Linkedin Live Security Deep Dive","en-us/blog/5-things-to-know-from-our-linkedin-live-security-deep-dive.yml","en-us/blog/5-things-to-know-from-our-linkedin-live-security-deep-dive",{"_path":727,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":728,"content":734,"config":740,"_id":742,"_type":14,"title":743,"_source":16,"_file":744,"_stem":745,"_extension":19},"/en-us/blog/7-steps-to-enhance-application-security-without-slowing-developer-velocity",{"title":729,"description":730,"ogTitle":729,"ogDescription":730,"noIndex":6,"ogImage":731,"ogUrl":732,"ogSiteName":686,"ogType":687,"canonicalUrls":732,"schema":733},"7 steps to enhance application security without slowing developer velocity","Learn how to incrementally enable scanning to successfully shift-left security while keeping development at pace.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099154/Blog/Hero%20Images/Blog/Hero%20Images/applicationsecurity_applicationsecurity.png_1750099154308.png","https://about.gitlab.com/blog/7-steps-to-enhance-application-security-without-slowing-developer-velocity","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"7 steps to enhance application security without slowing developer velocity\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Julie Byrne\"}],\n        \"datePublished\": \"2024-05-21\",\n      }",{"title":729,"description":730,"authors":735,"heroImage":731,"date":737,"body":738,"category":694,"tags":739},[736],"Julie Byrne","2024-05-21","Organizations are feeling an increased sense of urgency to ensure the security of their built applications by putting in place cybersecurity protocols. However, as they enable security analyzers on source code and related assets, they find that the amount of data they are getting in terms of potential vulnerabilities is overwhelming to development teams. This article provides seven steps to take to implement scans without dramatically slowing down developer velocity. This tutorial is based on my work with customers who have experienced this dilemma.\n\n## The need for increased application security\n\nApplication security has become a greater a focus for organizations in part because of the following reasons:\n\n- Recent [high-profile cyber attacks](https://www.cm-alliance.com/cybersecurity-blog/biggest-cyber-attacks-data-breaches-ransomware-attacks-february-2024) have had major business impacts, including long outage windows, stolen data, and ransoms being paid.\n- The U.S. government released a series of [executive orders concentrated on software supply chain security](https://www.whitehouse.gov/omb/briefing-room/2022/09/14/enhancing-the-security-of-the-software-supply-chain-to-deliver-a-secure-government-experience/) and now requires that vendors supply a [software bill of materials (SBOM)](https://www.cisa.gov/sbom) that lists the ingredients in terms of open source libraries that make up a software application.\n - Compliance standards such as [SOC2](https://about.gitlab.com/the-source/security/how-gitlab-can-help-you-prepare-for-your-soc-2-exam/), which mandate companies to validate the security of their applications, are becoming more common in many industries.\n\nOne way to meet this demand for increased application security is by enabling security scans, but that can be an overwhelming proposition. Consider, for example, a technology startup with Series A funding building a SaaS application. Security scans are crucial for compliance, but so is optimizing the velocity of new feature development. These goals can seem contradictory, at times. Organizations in this situation are often uncertain about what approach to take to ensure compliance standards are met and their applications are as secure as possible without bringing developer velocity to a halt.\n\n## How to keep development fast and secure\n\nHere are the steps to take to ensure that your development can keep pace while still meeting compliance and security requirements.\n\n### Step 1: Assess the current state of development\n\nYour starting point with security scans is going to be strongly dependent on the details of the applications you build, in terms of both the industries and customer base you serve, and the frameworks, languages, and cloud technologies used to build and deploy the application.  A company producing an embedded device, for example, will have a completely different set of concerns than a company producing a SaaS application. It's important to bring together your technology leaders, cybersecurity experts, business executives, and others with the appropriate business and technology expertise to understand:\n- the compliance standards that apply to the applications you're producing\n- the types potential vulnerabilities that present the biggest threat based on industry research and your application and network architecture\n\nKnowing these characteristics will assist in your development of your threat landscape: your application's identified and potential cyberthreats.\n\nIf you have a variety of applications, start small and test your scanning and vulnerability management program with a few pilot applications. Choose the applications that are the most critical and/or will provide the best validation and feedback to inform enhancements to your application security strategy.\n\nThis assessment will help identify what security scans you want to enable for these pilot applications.\n\n### Step 2: Enable security scans\n\nNext, you'll want to conduct initial scans of the pilot applications you identified in Step 1. The initial scans should be done outside of development pipelines so that you do not distract the developers who are implementing new features and bug fixes. In GitLab, you can use [scan execution policies](https://docs.gitlab.com/ee/user/application_security/policies/scan-execution-policies.html) to enable scheduled scans of the default branch.\n\n![7 steps app security - image 1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099164/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750099164066.png)\n\nYou should only enable the highest priority scans based on the threat landscape you identified in Step 1.  While every customer will be slightly different, GitLab customers commonly start with secrets detection and dependency scanning at a bare minimum.\n\n### Step 3: Evaluate scan results\n\nOnce you have the results of initial scans for pilot applications, you will want to analyze the results.\n\nAre there vulnerabilities that are false positives based on your specific application architecture?  One example of this might be a dependency scan finding vulnerabilities in libraries that are only used in a development environment as part of a test framework but are not used for the build of the production application. These vulnerabilities can be safely ignored.\n\nAre there vulnerabilities that are just “noise” and not really important? Many static application security testing (SAST) scanner default rule configurations will find hundreds of low severity vulnerabilities in source code that you might decide are not the most important thing to focus on right now.\n\nFinally, based on your knowledge of the applications, and the risk assessments performed, are there areas of potential vulnerabilities that have not been uncovered with the existing scans? You’ll want to understand where gaps lie that might need additional scanners or manual assessment.\n\n### Step 4: Adjust scan analyzers and rules used\n\nUse the evaluation of the initial scan results to define processes for vulnerability triaging and remediation. Then adjust the scanner rules to only focus on what’s most important. This is a crucial step to ensure that development velocity does not dramatically slow down due to development teams having many low-priority vulnerabilities to sort through as they implement code changes. For example, a SAST analyzer rule might find critical vulnerabilities in a code that runs on an IoT device. That device, however, has other security controls that effectively mitigate exploitability of a latent vulnerability in the embedded code. In this case, thevulnerabilities are not of concern and you can safely disable the rule.\n\nSimilarly, if you find that your testers commonly use personally identifiable information in test data that sometimes inadvertently gets committed to the code repository, then you will want to create a custom secrets detection rule that looks for the appropriate string patterns for this PII data.\n\nGitLab allows you to customize rulesets for [SAST](https://docs.gitlab.com/ee/user/application_security/sast/customize_rulesets.html) and [secrets detection](https://docs.gitlab.com/ee/user/application_security/secret_detection/pipeline/index.html#customizing-analyzer-settings). As you implement custom rulesets, be sure to clearly document rule customizations and rationale for each and review them periodically.\n\n### Step 5: Prioritize initial vulnerabilities for remediation\n\nBusiness, product, and development leaders should agree on the importance of remediating high priority vulnerabilities and convey that importance to development teams. It is crucial for development teams to plan to work on the highest priority vulnerability remediation along with feature work. Vulnerabilities with a clear and practical attack vector should be prioritized and added to the backlog.  Vulnerabilities that are not a priority for remediation can be left open in the confirmed state or be dismissed as an acceptable risk or a false positive.   Add notes to capture the dismissal reason for auditing purposes. This prioritization strategy is one more step that can prevent slowdowns in developer velocity.\n\n### Step 6: Enable scans in development pipelines\n\nAfter completing the five steps above, you now have enough information to formalize your security scan program and bring the developers for the pilot applications into the fold. You'll want to start to drive developer participation in application security sooner rather than later, but take an iterative approach.  Start small by introducing the highest priority scans, with any custom configurations identified in the initial scans, into development pipelines via triggered jobs defined in [scan execution policies](https://docs.gitlab.com/ee/user/application_security/policies/scan-execution-policies.html). Be sure to configure scan jobs to run in parallel with other CI jobs you've already defined for your application.\n\nMonitor pipeline times to ensure scans are not dramatically slowing down time to completion, and configure any extremely slow scans such as dynamic applications security testing to run on a scheduled basis instead of being triggered on commits to a feature branch. This will ensure that developers are still getting fast feedback as they are working on code changes for new features and bug fixes.\n\nAs much as possible, you will want to start with providing developer visibility of found vulnerabilities first without adding any enforcement or blocking of the merge of code changes.  The GitLab [merge request widget](https://docs.gitlab.com/ee/user/application_security/#merge-request) shows new potential vulnerabilities found in the feature branch to provide visibility to developers of the security impact of their code changes. If certain critical vulnerabilities are becoming commonplace, consider enabling [merge request approval policies](https://docs.gitlab.com/ee/user/application_security/policies/scan-result-policies.html) only for newly found critical vulnerabilities to put some guardrails in place without requiring too much extra process that slows down developers.\n\nAt the same time, educate the developers to understand what the security vulnerabilities mean and how to remediate them. GitLab integrates with the [security training providers](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/index.html#enable-security-training-for-vulnerabilities) Secure Code Warrior, Kontra, and SecureFlag to help your developers learn how to fix vulnerabilities, providing links on the vulnerability details page to the appropriate training resources that match a vulnerability identifier.\n\nLastly, drive a collaborative environment between development, security, and operations. Application security should be a joint initiative with clear priority across all roles. By helping developers understand potential vulnerabilities early in the software development lifecycle and remediate them when warranted, they will spend much less effort than having to remediate them at later stages, and that will allow teams to continue to have capacity for new feature development.\n\n### Step 7: Rinse and repeat\n\nCongratulations! You now have a security scan and vulnerability remediation program enabled for a set of pilot teams.  But the job is not done. You will want to focus on continuous improvement – incorporate what you learn from the pilot teams and iterate. Then, enable a second wave of teams, following all of the defined steps.  You'll want to continue with small sets of teams until security scans have been enabled across all relevant applications.\n\n## Read more\n\n- [Getting started with application security documentation](https://docs.gitlab.com/ee/user/application_security/get-started-security.html)\n- [How to tailor SAST and secret detection to your application context with custom rulesets](https://docs.gitlab.com/user/application_security/sast/customize_rulesets/)\n- [Webinar: Starting a Vulnerability Remediation Program](https://youtu.be/CS_GlJGtnpM?feature=shared)\n- [Video tutorial: Creating security policies - the basics (3:06)](https://www.youtube.com/watch?v=IZbCIKXz-wM)\n\n> Watch the on-demand [\"Vulnerability Management Strategies\" webinar](https://www.youtube.com/watch?v=CS_GlJGtnpM) and [review the accompanying slide deck](https://content.gitlab.com/viewer/663d56826ff2240911aac5f0).",[694,9],{"slug":741,"featured":91,"template":698},"7-steps-to-enhance-application-security-without-slowing-developer-velocity","content:en-us:blog:7-steps-to-enhance-application-security-without-slowing-developer-velocity.yml","7 Steps To Enhance Application Security Without Slowing Developer Velocity","en-us/blog/7-steps-to-enhance-application-security-without-slowing-developer-velocity.yml","en-us/blog/7-steps-to-enhance-application-security-without-slowing-developer-velocity",{"_path":747,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":748,"content":754,"config":762,"_id":764,"_type":14,"title":765,"_source":16,"_file":766,"_stem":767,"_extension":19},"/en-us/blog/7-tips-on-how-to-successfully-talk-to-execs-about-devsecops",{"title":749,"description":750,"ogTitle":749,"ogDescription":750,"noIndex":6,"ogImage":751,"ogUrl":752,"ogSiteName":686,"ogType":687,"canonicalUrls":752,"schema":753},"7 tips on how to successfully talk to execs about DevSecOps","If you want to begin using DevSecOps to improve software development, you need to get business executives behind your plan. Here are tips to do just that.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749670694/Blog/Hero%20Images/how-to-keep-remote-teams-engaged-cover.jpg","https://about.gitlab.com/blog/7-tips-on-how-to-successfully-talk-to-execs-about-devsecops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"7 tips on how to successfully talk to execs about DevSecOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sharon Gaudin\"}],\n        \"datePublished\": \"2023-07-12\",\n      }",{"title":749,"description":750,"authors":755,"heroImage":751,"date":757,"body":758,"category":10,"tags":759},[756],"Sharon Gaudin","2023-07-12","\nIf you want to begin using DevSecOps to speed, secure, and improve software development, you need to get business executives behind your plan. But talking with leadership – especially C-suite executives – isn’t always easy.\n\nSoftware development teams want to use DevSecOps because it will reduce hands-on work, make the development process more efficient, [foster collaboration](/blog/5-ways-collaboration-boosts-productivity-and-your-career/), [improve security](/the-source/security/how-to-strengthen-security-by-applying-devsecops-principles/), and speed development and deployment. Getting executives to understand how that all translates into [business benefits](/blog/five-essential-business-benefits-a-devops-platform-gives-smbs/) is the key here. That’s what will spur them to OK a DevSecOps adoption.\n\n> **Be sure to download our latest guide *[How to drive business success with DevSecOps](https://page.gitlab.com/resources-ebook-devsecops-success.html?utm_campaign=devsecopsplat&utm_content=ebookdevsecopssuccess)* for more advice.**\n\nTo help executives understand the technical and business benefits of [DevSecOps](/blog/its-time-to-put-the-sec-in-devsecops/) there are pitfalls you’ll need to avoid, as well as things you should make sure you do and discuss. Let’s dive into 7 things to consider right from the start.\n\n## 1. Know your audience\nEveryone is different. Some executives want every little detail. Others want a quick overview. And if, for instance, you’re talking with a CEO, focus on reducing costs and how more efficient and faster production can boost revenue and improve time to market. For CIOs, focus on productivity and efficiency. Tell them how automation and artificial intelligence (AI) features will save teams time and hands-on work.\n\n## 2. Find a champion\nIf you’re going to be walking into a boardroom packed with C-suite executives or having a small meeting with a CEO, it helps to have backup. Find an executive who knows the language of business and key business drivers and pitch the idea of using DevSecOps to get her backing. Then she can help you make the pitch to other executives.\n\n## 3. Make sure you have a plan\nBefore talking to an executive, you first need to draft a plan. Create a basic outline that gives you guidance about the key points to touch on, but also leaves room to take questions and feedback. Make sure you listen as much as you talk. Meetings are learning opportunities.\n\n## 4. Don’t geek out on the tech\nRemember that you are talking to business people. It’s easy for a technical person to fall back on using technical lingo and talking about the excitement of using the shiniest tools. But that’s not going to get someone far with most executives. Even a CTO, who is a technical person, is focused on the business – and how any technology is going to support that business or weigh it down. Don't use technical jargon or acronyms. Convey engineering objectives into a language of profit and loss. Tell execs why migrating to a DevSecOps platform will make the software development team, and the company as a whole, more successful.\n\n## 5. Do your homework\nIf you work for a public company, listen to the quarterly reports to learn about immediate business objectives and long-term strategic goals. Have a coffee chat with or shadow someone who works in financial planning, analysis, and/or accounting. Learn from your colleagues how the company makes money and what its business needs are. Understand challenges, like security issues, [compliance issues](/blog/top-5-compliance-features-to-leverage-in-gitlab/), or competitors coming out with new features faster. Then address those challenges. Make sure your presentation focuses on the company’s specific needs and any potential future challenges.\n\n“I would recommend always starting by figuring out the business needs first,” says [Fatima Sarah Khalid](https://gitlab.com/sugaroverflow), developer evangelist at GitLab. “How does this bring value to the organization’s customers and how does this impact the company? Will it save money, unlock a new customer segment, open up new channels, or boost production and efficiency? These are the kind of strategic levers that are most helpful for leadership to hear.”\n\n## 6. Focus on benefits to the executives\nOf course, executives will want to know how DevSecOps will benefit the business that they’re running, but they’ll also want to know how it can benefit them and the specific job they’re doing. Let executives know that a DevSecOps platform will give them visibility into the entire software development lifecycle so they can see where projects slow down or progress, giving them more insight and control. And make it clear that an end-to-end platform fosters a culture where everyone, from customer service to marketing and the C-suite, can collaborate.\n\n## 7. Don’t forget the money\nAs you plan out what to talk about with executives and what business challenges to focus on, remember that money always has to be part of the conversation. Since you likely will be reducing a complex and costly toolchain with the adoption of a DevSecOps platform, estimate the savings in both cost and time that will come from cutting that toolchain. Point out the savings, in terms of money and brand image, by reducing security vulnerabilities. Management also is going to want you to estimate how much it will cost to migrate to a platform, along with the human hours needed, and an adoption timeline.\n\n“Tech people can never forget that executives are very focused on ROI,” says [Ayoub Fandi](https://gitlab.com/ayofan), senior field security engineer at GitLab. “It’s always a central issue. They need to understand if any decision will bring them closer to their business goals. Adopting a DevSecOps platform can be a massive cost reduction. Each year companies spend more money on IT so if they can learn a way to spend less, it’ll be very welcome information.”\n\nRemember that leadership likely is looking for reasons to say yes. You just need to provide them with those reasons – and make sure they’re solid business reasons. Make it clear what an adoption will look like in practice. Show them [case studies](/customers/) of other companies that have made the move.\n\nAnd the impact of enabling executives to understand the benefits of DevSecOps go beyond a single adoption. Learning how to understand an organization’s business needs and strategy, and learning the language of business are [great skills for anyone in tech](/blog/best-advice-for-your-devops-career-keep-on-learning/) to have. Continuing to educate yourself and pursuing knowledge on the business side are top ways to increase your standing in your company, your hireability, and [your paycheck](/blog/four-tips-to-increase-your-devops-salary/).\n\nGet even more advice in our our latest guide *[How to drive business success with DevSecOps](https://page.gitlab.com/resources-ebook-devsecops-success.html?utm_campaign=devsecopsplat&utm_content=ebookdevsecopssuccess)*, available for download now.\n",[9,760,761],"collaboration","careers",{"slug":763,"featured":6,"template":698},"7-tips-on-how-to-successfully-talk-to-execs-about-devsecops","content:en-us:blog:7-tips-on-how-to-successfully-talk-to-execs-about-devsecops.yml","7 Tips On How To Successfully Talk To Execs About Devsecops","en-us/blog/7-tips-on-how-to-successfully-talk-to-execs-about-devsecops.yml","en-us/blog/7-tips-on-how-to-successfully-talk-to-execs-about-devsecops",{"_path":769,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":770,"content":776,"config":783,"_id":785,"_type":14,"title":786,"_source":16,"_file":787,"_stem":788,"_extension":19},"/en-us/blog/a-developers-guide-to-building-an-ai-security-governance-framework",{"title":771,"description":772,"ogTitle":771,"ogDescription":772,"noIndex":6,"ogImage":773,"ogUrl":774,"ogSiteName":686,"ogType":687,"canonicalUrls":774,"schema":775},"A developer's guide to building an AI security governance framework","Learn the strategies and practices to adopt for secure and responsible development and use of AI.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664638/Blog/Hero%20Images/applicationsecurity.png","https://about.gitlab.com/blog/a-developers-guide-to-building-an-ai-security-governance-framework","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"A developer's guide to building an AI security governance framework\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Ayoub Fandi\"}],\n        \"datePublished\": \"2024-04-23\",\n      }",{"title":771,"description":772,"authors":777,"heroImage":773,"date":779,"body":780,"category":781,"tags":782},[778],"Ayoub Fandi","2024-04-23","Artificial Intelligence (AI) has firmly established itself as a pillar of digital transformation, disrupting industries, increasing efficiency, and providing unmatched access to large data sets. AI also raises profound questions regarding security governance. How do I ensure I can leverage the best of what AI has to offer while mitigating its potential security risks? As [AI continues to advance](https://about.gitlab.com/topics/devops/the-role-of-ai-in-devops/), there is a growing need for strong oversight and accountability. This article delves into the complex landscape of AI security governance, exploring various frameworks, strategies, and practices that organizations like GitLab are adopting to ensure the responsible development of AI technologies and features.\n\n## Greater scrutiny on AI\n\n### AI: Single term, numerous realities\nAI isn't a monolithic entity - it encompasses a spectrum of technologies and applications. From machine learning algorithms that power recommendation systems to advanced natural language processing models like Anthropic’s Claude 3, each AI system brings its unique set of opportunities and challenges.\n\nAccording to [a 2023 MITRE report](https://www.mitre.org/sites/default/files/2023-06/PR-23-1943-A-Sensible-Regulatory-Framework-For-AI-Security_0.pdf), three main areas of AI currently exist:\n\n1. **AI as a subsystem**\n\n\u003Cp>\u003C/p>\u003Ci>\"AI is embedded in many software systems. Discrete AI models routinely perform machine perception and optimization functions, from face recognition in photos uploaded to the cloud, to dynamically allocating and optimizing network resources in 5G wireless networks.\n  \u003Cp>\u003C/p>\n\"There are a wide range of vulnerabilities and threats against these types of AI subsystems – from data poisoning attacks to adversarial input attacks – that can be used to manipulate subsystems.\"\u003C/i>\u003Cp>\u003C/p>\n\n2. **AI as human augmentation**\n\u003Cp>\u003C/p>\u003Ci>\"Another application of AI is in augmenting human performance, allowing a person to operate with much larger scope and scale. This has wide-ranging implications for workforce planning as AI has the potential to increase productivity and shift the composition of labor markets, similar to the role of automation in the manufacturing industry. \n  \u003Cp>\u003C/p>\n\"While sophisticated hackers and military information operations can already generate believable content today using techniques such as computer-generated imagery, LLMs will make that capability available to anyone, while increasing the scope and scale at which the professionals can operate.\"\u003C/i>\u003Cp>\u003C/p>\n\n3. **AI with agency**\n\u003Cp>\u003C/p>\u003Ci>\"A segment of the tech community is increasingly concerned about scenarios where sophisticated AI could operate as an independent, goal-seeking agent. While science fiction historically embodied this AI in anthropomorphic robots, the AI we have today is principally confined to digital and virtual domains.\n\u003Cp>\u003C/p>\n\"One scenario is an AI model given a specific adversarial agenda. Stuxnet is perhaps an early example of sophisticated, AI-fueled, goal-seeking malware with an arsenal of zero-day attacks that ended up escaping onto the internet.\"\u003C/i>\u003Cp>\u003C/p>\n\nYou can focus your efforts in terms of security governance based on which areas your company is looking to adopt and the expected business benefits.\u003Cp>\u003C/p>\n\n### Frameworks for AI security governance\nFor effective AI security governance, we must navigate the complex landscape of guidelines and principles developed by various organizations.\n\nGovernments, international organizations, and tech companies have all played their part in shaping AI security governance frameworks. You can review the frameworks below and choose those that are relevant and/or apply to your organization:\n\n- [NIST AI Risk Management Framework (AI RMF)](https://nvlpubs.nist.gov/nistpubs/ai/NIST.AI.100-1.pdf)\n- [Google’s Security Artificial Intelligence Framework](https://services.google.com/fh/files/blogs/google_secure_ai_framework_approach.pdf)\n- [OWASP Top 10 for LLMs](https://owasp.org/www-project-top-10-for-large-language-model-applications/assets/PDF/OWASP-Top-10-for-LLMs-2023-v1_0.pdf)\n- [The UK’s NCSC Principles for the Security of Machine Learning](https://www.ncsc.gov.uk/files/Principles-for-the-security-of-machine-learning.pdf)\n\nWhile these frameworks provide valuable guidance, they also introduce complexity. Organizations must determine which apply to their AI usage and how they align to their practices. Moreover, the dynamic nature of AI requires continuous adaptation to stay secure.\n\nSomething to note is that if you read through these frameworks, you’ll notice that numerous controls overlap with standard security best practices. This isn’t a coincidence. A strong overall security program is a prerequisite for proper AI security governance.\n\n## How-to: AI security governance\n### The why and the what\nAI security governance starts with understanding what AI technologies your organization is using or developing, why you are using them, and where these technologies fit into your operations. It's essential to define clear objectives and identify potential security risks associated with AI deployment. This introspection lays the foundation for effective AI security governance.\n\n#### The why\n\nUnderstanding the \"why\" behind each AI application is pivotal to build effective security governance. Each AI system deployed has to serve a specific purpose. Is AI being utilized to enhance customer experiences, automate manual tasks, or support the decision-making process? \n\nBy uncovering the motivations driving AI initiatives, organizations can align these projects with their broader business objectives. This alignment ensures that AI investments are strategically focused, delivering value in line with organizational goals. It also aids in prioritizing AI systems that have a more significant impact on the core mission of the company.\n\n#### The what\nIn the realm of AI security governance, the foundational step is conducting a comprehensive inventory of all AI systems, algorithms, and data sources within your organization. This includes meticulously cataloging all AI technologies in use, ranging from machine learning models and natural language processing algorithms to computer vision systems. This would also involve identifying the data sources feeding these AI systems, and their origins (internal databases, customer interactions, or third-party data providers). Such an inventory provides three main benefits: \n- to gain a holistic understanding of the AI ecosystem within the organization \n- to establish a strong basis for monitoring, auditing, and managing these assets effectively\n- to focus security efforts on the high-risk/critical areas\n\n### How to develop a security risk management program\nA robust security risk management program is at the core of responsible AI security governance. The critical building blocks for this program are the what and the why we discussed earlier. \n\nSpecificities of AI make security risk management more complex. In the NIST AI RMF mentioned earlier, numerous challenges are highlighted, including:\n\n- Difficult to measure AI-related security risks\n    - Potential security risks could emerge from the AI model, the software on which you are training the model, or the data ingested by the model. Different stages of the AI lifecycle might also trigger specific security risks depending on which actors (producers, developers, or consumers) are leveraging the AI solution.\n- Risk tolerance threshold might be complex to determine \n    - As the potential security risks aren’t easily identifiable, determining the risk tolerance your organization can withstand regarding AI can be a very empirical exercise.\n- Not considering AI in isolation \n    - Security governance of AI systems should be part of your security risk management strategy. Different users might have different parts of the overall picture. Ensuring you have complete information and full visibility into the AI lifecycle is critical to making the best decisions.\n\nSecurity risk management should be an ongoing process, adapting to the quickly evolving AI landscape. Reassessing the program, reviewing assumptions regarding the environment and involving additional business stakeholders are activities that should be happening on a regular basis.\n\n## AI security governance and the GitLab DevSecOps platform\n### Using AI to power DevSecOps \nLet’s take [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our suite of AI capabilities to help power DevSecOps workflows, as an example. [GitLab Duo Code Suggestions](https://about.gitlab.com/solutions/code-suggestions/) helps developers write code more efficiently by using generative AI to assist in software engineering tasks. It works either through code completion or through code generation using natural language code comment blocks.\n\nTo ensure it can be fully leveraged, security needs of potential users and customers have to be considered. As an example, data used to produce Code Suggestions is immediately discarded by the AI models. \n\nAll of GitLab’s AI providers are subject to contractual terms with GitLab that prohibit the use of customer content for the provider’s own purposes, except to perform their independent legal obligations. [GitLab’s own privacy policy](https://about.gitlab.com/privacy/) prevents us from using customer data to train models without customer consent. \n\nOf course, to fully benefit from Code Suggestions, you should:\n- understand and review all suggestions to see if they align with your development guidelines\n- limit providing sensitive information or proprietary code in prompts \nensure the suggestion follows the same secure coding guidelines your company has\n- review the code using automated scanning for vulnerable dependencies, input validation and output sanitization, as well as license checks\n\n### Securing AI\nManaging the output of AI systems is equally important as managing the input. Security scanning tools can help identify vulnerabilities and potential threats in AI-generated code. \n\nManaging AI output requires a systematic approach to code review and validation. Organizations should [integrate security scanning tools into their CI/CD pipelines](https://docs.gitlab.com/ee/user/application_security/), ensuring that AI-generated code is checked for security vulnerabilities before deployment. Automated security checks can help detect vulnerabilities early in the development process, reducing the risk of potential vulnerable code stemming from suggested code blocks being merged.\n\nFor any GitLab Duo generated code, changes are managed via merge requests which trigger your CI pipeline (including any security and code quality scanning you have configured). This ensures any governance rules you have set up for your merge requests like required approvals are enforced.\n\nAI systems are systems. Existing security controls apply to AI systems the same way they would apply to the rest of your environment. Common security controls around application security still apply, including [security reviews](https://docs.gitlab.com/ee/user/project/merge_requests/reviews/data_usage.html), security scanning, [threat modeling](https://danielmiessler.com/p/athi-an-ai-threat-modeling-framework-for-policymakers), encryption, etc. The [Google Secure AI Framework](https://services.google.com/fh/files/blogs/google_secure_ai_framework_approach.pdf) highlights these six elements:\n- expand strong security foundations to the AI ecosystem\n- extend detection and response to bring AI into an organization’s threat universe\n- automate defenses to keep pace with existing and new threats\n- harmonize platform-level controls to ensure consistent security across the organization\n- adapt controls to adjust mitigations and create faster feedback loops for AI deployment\n- contextualize AI system risks in surrounding business processes\n\nIf you have a strong security program, managing AI will be an extension of your current program and account for specific risks and vulnerabilities.\n\n## How GitLab Duo is secured\nGitLab recognizes the significance of security in AI governance. Our very strong security program is focused on ensuring our customers can fully leverage [GitLab Duo](https://docs.gitlab.com/ee/user/ai_features.html) in a secure manner. This is how the security departments are collaborating to secure GitLab’s AI features GitLab:\n- **Security Assurance:** Seeks to address our compliance requirements regarding security, that AI security risks are identified and properly managed, and that our customers understand how we secure our application, infrastructure, and services.\n\n- **Security Operations:** Monitors our infrastructure and quickly responds to threats using a team of skilled engineers as well as automation capabilities, helping to ensure AI features aren’t abused or used in a malevolent manner.\n\n- **Product Security:** Helps the product and engineering teams by providing security expertise for our AI features and helping to secure the underlying infrastructure on which our product is hosted.\n\n- **Corporate Security and IT Operations:** Finds potential vulnerabilities in our product to proactively mitigate and support other departments by performing research on relevant security areas.\n\nOur Security team works closely with GitLab's Legal and Corporate Affairs team to ensure our framework for AI security governance is comprehensive. The recent launch of the [GitLab AI Transparency Center](https://about.gitlab.com/blog/introducing-the-gitlab-ai-transparency-center/) showcases our commitment to implementing a strong AI governance. We published our AI ethics principles as well as our AI continuity plan to demonstrate our AI resiliency.\n\n## Learn more\nAI security governance is a complex area, especially as the field is in a nascent form. As AI continues to support our workflows and accelerate our processes, responsible AI security governance becomes a key pillar of any security program. By understanding the nuances of AI, enhancing your risk management program, and using AI features that are developed responsibly, you can ensure that AI-powered workflows follow the principles of security, privacy, and trust. \n\n>  Learn more about [GitLab Duo AI features](https://about.gitlab.com/gitlab-duo/).\n","ai-ml",[717,9,694,186],{"slug":784,"featured":91,"template":698},"a-developers-guide-to-building-an-ai-security-governance-framework","content:en-us:blog:a-developers-guide-to-building-an-ai-security-governance-framework.yml","A Developers Guide To Building An Ai Security Governance Framework","en-us/blog/a-developers-guide-to-building-an-ai-security-governance-framework.yml","en-us/blog/a-developers-guide-to-building-an-ai-security-governance-framework",{"_path":790,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":791,"content":797,"config":804,"_id":806,"_type":14,"title":807,"_source":16,"_file":808,"_stem":809,"_extension":19},"/en-us/blog/achieve-slsa-level-2-compliance-with-gitlab",{"title":792,"description":793,"ogTitle":792,"ogDescription":793,"noIndex":6,"ogImage":794,"ogUrl":795,"ogSiteName":686,"ogType":687,"canonicalUrls":795,"schema":796},"Achieve SLSA Level 2 compliance with GitLab","Compliance mandates call for controls to prevent software tampering, improve integrity of builds and artifacts, and support attestation. Here's how GitLab can help.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749667094/Blog/Hero%20Images/container-security.jpg","https://about.gitlab.com/blog/achieve-slsa-level-2-compliance-with-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Achieve SLSA Level 2 compliance with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sandra Gittlen\"}],\n        \"datePublished\": \"2022-11-30\",\n      }",{"title":792,"description":793,"authors":798,"heroImage":794,"date":800,"body":801,"category":694,"tags":802},[799],"Sandra Gittlen","2022-11-30","\n\nOrganizations are under intense pressure from governing bodies to attest to the fact that their software supply chains have not been tampered with. The industry has come together to create an industry standard, Supply chain Levels for Software Artifacts ([SLSA](https://slsa.dev/)), to guide companies on exactly how to achieve such attestation. GitLab helps organizations comply with SLSA requirements by incorporating attestation capabilities into its DevSecOps platform.\n\n“Although SLSA compliance is relatively new, security-conscious DevOps teams are already adopting its requirements to demonstrate their software is trustworthy,” says [Sam White](https://gitlab.com/sam.white), Group Manager of Product for the [Govern stage](/direction/govern/) at GitLab. \n\nGitLab Federal CTO [Joel Krooswyk](https://gitlab.com/jkrooswyk) agrees. “DevOps teams will need to understand attestation as part of new government regulations around the larger release verification process. Vendors, third-party development and integration providers, and other data-sensitive industries will be required to adhere to published guidance,” he says. “GitLab helps companies across all sectors address these compliance mandates.”\n\n## What is SLSA?\n\nSLSA first launched in 2021 in response to calls for a framework to [secure software supply chains](/blog/the-ultimate-guide-to-software-supply-chain-security/). SLSA provides a checklist of standards and controls to prevent tampering, improve integrity, and secure packages and infrastructure. The goal is for software developers to be able to use best practices to [guarantee the integrity](/blog/securing-the-software-supply-chain-through-automated-attestation/) of each and every artifact, more specifically that the source code users are relying on is the code they are actually using and that the build machine producing the artifacts was secure.\n\nThe SLSA standard has four levels that examine the builds, sources, and dependencies in open source and commercial software. The levels build on one another, growing from simple visibility and being able to generate provenance to providing the highest assurances of build integrity and measures for dependency management.\n\nGitLab’s DevSecOps platform currently supports SLSA Levels 1 and 2. GitLab makes it simple for users to comply with these first two levels, according to White. “Whether you are working on an open source project or developing commercial software, there is no reason not to generate provenance for your code and attest to it. Even if you are just tinkering around, there is no harm in following the SLSA specifications,” he says.\n\n## How to generate artifact metadata with the GitLab Runner\n\nGitLab enables users to generate artifact metadata following the SLSA format for any artifacts that are built on the platform. Because the process happens within the GitLab Runner, without needing third-party software, it prevents the opportunity for any tampering or corruption of the attestation itself.\n\nTo generate an attestation, all that is required is to simply set `RUNNER_GENERATE_ARTIFACTS_METADATA: true` in your `.gitlab-ci.yml` file. You can set the variable globally or on a per-job basis. A CI pipeline then will produce a data.txt file and generate metadata to describe how that file was produced and verify the origin of it or the provenance of it. Users can download this artifact file, which comes as a zip file with the two files inside of it – one is the data.txt and the other is an artifacts metadata .json file.\n\nThe file offers metadata about what was done and it lists out all of the different parameters and input points, including the SHA hash of the file itself as well as the hash of the repository.\n\n“This level of detail enables someone to come in later and get an idea of the steps that were taken in order to produce it as well as information about where it was built so someone can protect their artifacts and reduce the chance of tampering,” White says.\n\n\nFollow the step-by-step instructions here:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/MlIdqrDgI8U\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nThe idea of all this, White explains, is to provide a recipe for how the file was built so that if a DevOps team needed to replicate it, they could use those instructions on another machine and get the same build.\n\n## GitLab’s next SLSA step\n\nAs SLSA matures, GitLab plans to [introduce additional features](/direction/supply-chain/), such as the ability to sign the attestation, to guide DevOps teams through SLSA Levels 3 and 4. For instance, users currently can use an external code signer to verify the signing and verify the attestation but the ideal state would be to integrate code signing functionality directly into the platform. GitLab also plans to add capabilities that enable more detailed inspection and validation of attestations from upstream dependencies.\n\n**Disclaimer This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab.**\n\n",[9,694,803,186],"open source",{"slug":805,"featured":6,"template":698},"achieve-slsa-level-2-compliance-with-gitlab","content:en-us:blog:achieve-slsa-level-2-compliance-with-gitlab.yml","Achieve Slsa Level 2 Compliance With Gitlab","en-us/blog/achieve-slsa-level-2-compliance-with-gitlab.yml","en-us/blog/achieve-slsa-level-2-compliance-with-gitlab",{"_path":811,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":812,"content":818,"config":828,"_id":830,"_type":14,"title":831,"_source":16,"_file":832,"_stem":833,"_extension":19},"/en-us/blog/actioning-security-vulnerabilities-in-gitlab-premium",{"title":813,"description":814,"ogTitle":813,"ogDescription":814,"noIndex":6,"ogImage":815,"ogUrl":816,"ogSiteName":686,"ogType":687,"canonicalUrls":816,"schema":817},"How to action security vulnerabilities in GitLab Premium","Learn step-by-step how to process detected vulnerabilities and spawn merge request approval rules from critical vulnerabilities.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099637/Blog/Hero%20Images/Blog/Hero%20Images/security-pipelines_security-pipelines.jpg_1750099637178.jpg","https://about.gitlab.com/blog/actioning-security-vulnerabilities-in-gitlab-premium","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to action security vulnerabilities in GitLab Premium\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sam Morris\"},{\"@type\":\"Person\",\"name\":\"Noah Ing\"}],\n        \"datePublished\": \"2023-03-13\",\n      }",{"title":813,"description":814,"authors":819,"heroImage":815,"date":822,"body":823,"category":694,"tags":824},[820,821],"Sam Morris","Noah Ing","2023-03-13","GitLab Premium features several security scanners you can leverage to detect\nvulnerabilities. However, when you incorporate the scanners into your\nproject pipelines and the scanning job succeeds, you'll want feedback on\nwhether you are introducing vulnerabilities into the codebase. This tutorial\nprovides a mechanism to require a merge request approval if a scanner\navailable on GitLab Premium finds a critical vulnerability.\n\n\n*While this tutorial shows how to add some process around actioning\nvulnerabilities, we have more robust, governed, and user-friendly\nfunctionality available in GitLab Ultimate called a [Scan Result\nPolicy](https://docs.gitlab.com/ee/user/application_security/policies/scan-result-policies.html).\nThe solution outlined here does not seek to replace that functionality, but\nrather augment the scan results available in GitLab Premium. If you are an\nUltimate user or if you want to compare the two experiences, then you should\ncheck out [this video\nintroduction](https://www.youtube.com/watch?v=w5I9gcUgr9U&ab_channel=GitLabUnfiltered)\ninstead.*\n\n\nLearn how to do the following:\n\n\n1. Set up a .gitlab-ci.yml\n\n2. Add in a vulnerability processing script\n\n3. Require approval if vulnerabilities are found \n\n\n### Prerequisites\n\n\n- A project with GitLab Premium\n\n- A gitlab-ci.yml\n\n- A project access token\n\n- Basic knowledge of Python\n\n- 5 minutes (or less)\n\n\n## Setup the gitlab-ci.yml \n\n\nThis is how the GitLab CI pipeline of our test project looks visually. Below\nwe will break down the individual stages.\n\n\nAdd the following to your .gitlab-ci.yml:\n\n\n```yaml\n\nsecret_detection:\n  artifacts:\n    paths:\n      - gl-secret-detection-report.json\n\nprocess_secret_detection:\n   image: python:3.7-alpine3.9\n   stage: process_vulns\n   needs:\n    - job: secret_detection\n      artifacts: true\n   before_script:\n      pip install python-gitlab\n   script:\n     - python3 process_vulns.py gl-secret-detection-report.json $PROJECT_ACCESS_TOKEN $CI_PROJECT_ID $CI_COMMIT_SHA\n```\n\n\nA breakdown of what is going on above:\n\n- gl-secret-detection-report.json needs to be overriden so it’s being stored\nas an artifact in the secret_detection job.\n\n- The process_secret_detection job is dependent on secret_detection's\nartifact so we have added a needs keyword requiring successful completion of\nthe secret_detection job.\n\n- pip installs the python-gitlab dependency so that the process_vulns.py can\nleverage GitLab API calls.\n\n- The process_vulns.py is taking in four arguments:\n   - gl-secret-detection-report.json is the JSON report produced from the secret_detection scanner. If you would like to take in another report this will need to be modified.\n   - $PROJECT_ACCESS_TOKEN needs to be added; review the instructions on creating a project access token in the next step.\n   - $CI_PROJECT_ID and $CI_COMMIT_SHA are both GitLab CI environment variables that will automatically be inferred.\n\n### Create a project access token\n\n\nTo create a project access token:\n\n1. On the top bar, select Main menu > Projects and find your project.\n\n2. On the left sidebar, select Settings > Access Tokens.\n\n3. Enter a name. The token name is visible to any user with permissions to\nview the project.\n\n4. Optional. Enter an expiry date for the token. The token expires on that\ndate at midnight UTC. An instance-wide maximum lifetime setting can limit\nthe maximum allowable lifetime in self-managed instances.\n\n5. Select a role for the token.\n\n6. Select the desired scopes.\n\n7. Select Create project access token.\n\n8. Add this newly created project access token to your CI/CD variables in\nyour project settings!\n\n\n## Add in the vulnerability processing script\n\n\n[The process_vulns.py script can be found\nhere.]((https://gitlab.com/gl-demo-premium-smorris/secure-premium-app/-/blob/main/process_vulns.py)\nCopy that file into your project.\n\n\nThe goal of this script is to require approval from an author (or group of\nauthors) if a critical vulnerability is found.\n\n\n**Note:** You will need to [change the user ID in the\nprocess_vulns.py](https://gitlab.com/gl-demo-premium-smorris/secure-premium-app/-/blame/main/process_vulns.py#L40)\nto match the user ID of your designated Approver at your organization.\n\n\nThe following is a breakdown of what the script is doing:\n\n\n- JSON security reports are loaded in, if there any vulnerabilities they are\nparsed.\n\n- An authentication with GitLab is run using the project access token to\ninteract with the project.\n\n- If vulnerabilities are not found, then it will print to the GitLab CI\nLogs: “No vulnerabilities are found.”\n\n- If a critical vulnerability is found, then it will require an approval.\n\n\nRun the pipeline and voila! Your pipeline now requires approvers if a\ncritical vulnerability is found!\n\n\n### Demo\n\n\nWatch a video demonstration of how to action security vulnerabilities in\nGitLab Premium, presented by Sam Morris:\n\n\n\u003Ciframe width=\"560\" height=\"315\"\nsrc=\"https://www.youtube.com/embed/Cld36OZrLFo\" title=\"YouTube video player\"\nframeborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write;\nencrypted-media; gyroscope; picture-in-picture; web-share\"\nallowfullscreen>\u003C/iframe>\n\n\n#### Caveats\n\n- This is mimicking a Scan Result Policy; it is not a replacement.\n\n- This currently only requires approval for a critical vulnerability, and\neach new rule would have to be added to the script.\n\n- This script lives within the same location as your project, so there is no\nrestriction on who can modify the script, breaking separation of duties at\nscale.\n\n- Approval rules are not removed once the vulnerability is fixed.\n\n- Approvers' IDs need to be hardcoded and maintained in the script file.\n\n- Since there is no vulnerability record generated, you cannot track the\nvulnerabilities over time in your application.\n\n- Vulnerabilities are not fed into a report or security dashboard, so this\nonly reports merge request vulnerabilities.\n\n\n## References\n\n- [Create a project access\ntoken](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html#create-a-project-access-token)\n\n- [Setting up CI/CD\nvariables](https://docs.gitlab.com/ee/ci/variables/#define-a-cicd-variable-in-the-ui)\n\n- [Secure Premium app\nproject](https://gitlab.com/gl-demo-premium-smorris/secure-premium-app/-/blob/main/process_vulns.py)\n\n\n## Related posts\n\n- [GitLab's commitment to enhanced application security in the modern DevOps\nworld](/blog/security-gitlab-15/)\n\n- [How to become more productive with Gitlab\nCI](/blog/how-to-become-more-productive-with-gitlab-ci/)\n\n- [GitLab CI DRY\nDevelopment](/blog/keeping-your-development-dry/)\n\n\n_Cover image by [Christopher\nBurns](https://unsplash.com/@christopher__burns?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\non [Unsplash](https://www.unsplash.com)._\n",[694,9,825,826,827],"CI","CD","tutorial",{"slug":829,"featured":6,"template":698},"actioning-security-vulnerabilities-in-gitlab-premium","content:en-us:blog:actioning-security-vulnerabilities-in-gitlab-premium.yml","Actioning Security Vulnerabilities In Gitlab Premium","en-us/blog/actioning-security-vulnerabilities-in-gitlab-premium.yml","en-us/blog/actioning-security-vulnerabilities-in-gitlab-premium",{"_path":835,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":836,"content":842,"config":849,"_id":851,"_type":14,"title":852,"_source":16,"_file":853,"_stem":854,"_extension":19},"/en-us/blog/ai-assisted-code-suggestions",{"title":837,"description":838,"ogTitle":837,"ogDescription":838,"noIndex":6,"ogImage":839,"ogUrl":840,"ogSiteName":686,"ogType":687,"canonicalUrls":840,"schema":841},"How AI-assisted code suggestions will advance DevSecOps","In this second blog in our ‘Future of AI/ML in DevSecOps’ series, find out the impact of AI Assisted code suggestions on the software development lifecycle.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662840/Blog/Hero%20Images/ai-experiment-stars.png","https://about.gitlab.com/blog/ai-assisted-code-suggestions","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How AI-assisted code suggestions will advance DevSecOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Neha Khalwadekar\"}],\n        \"datePublished\": \"2023-03-23\",\n      }",{"title":837,"description":838,"authors":843,"heroImage":839,"date":845,"body":846,"category":781,"tags":847},[844],"Neha Khalwadekar","2023-03-23","\n\n\u003Ci>This blog post is part of an ongoing series about GitLab's journey to [build and integrate AI/ML into our DevSecOps platform](/blog/ai-ml-in-devsecops-series/). The series starts here: [What the ML is up with DevSecOps and AI?](/blog/what-the-ml-ai/). Throughout the series, we'll feature blogs from our product, engineering, and UX teams to showcase how we're infusing AI/ML into GitLab.\u003C/i>\n\nArtificial intelligence (AI) and machine learning (ML) have made incredible technological strides and are now poised to [impact the software development process](/topics/devops/the-role-of-ai-in-devops/). As we can see, AI code suggestion proposals have already had a tremendous influence in helping programmers reduce repetitive tasks. AI-assisted code suggestions will enable developers to speed up coding, debugging, refactoring, documentation, and many more tasks, greatly enhancing the software development lifecycle (SDLC).\n\n![Trends adopting AI/ML from GitLab's DevSecOps Survey](https://about.gitlab.com/images/blogimages/ai-ml-adoption-03-2023.png){: .shadow}\n\n## What are suggestions for AI-assisted code?\n\nML techniques are used in AI-assisted code suggestions to assess code and recommend improvements. These recommendations involve modifying the syntax, streamlining the organization of the code, or suggesting more effective methods. By lowering errors, increasing effectiveness, and providing optimization advice, the aim is to assist developers in writing better code faster.\n\n![Animated gif image of code suggestions](https://about.gitlab.com/images/15_9/DemoFastApi.gif){: .shadow}\n\n## How can AI-assisted code suggestions help?\n\nAI-assisted code suggestions can substantially improve the programming experience by reducing errors and helping programmers write code faster, which will help reproduce the much higher production code quality. \n\nHere are some of those SDLC improvements:\n\n- **Decreased errors, increased accuracy.** The capacity of AI-assisted code suggestions to decrease errors and increase accuracy is a critical advantage over manually written code. Developers can prevent common syntax errors, organize their code better, and boost algorithm performance with code suggestions. This leads to more dependable and effective code, which produces fewer defects and higher-quality software.\n- **A rise in productivity.** AI-assisted code suggestions can increase developers' efficiency by producing better code faster and more efficiently, saving time and money. Additionally, code suggestions can automate repetitive activities like formatting code, freeing engineers to concentrate on more complex jobs.\n- **Improved collaboration.** AI-assisted code recommendations can improve developer collaboration. Code suggestions can ensure all developers are on the same page by offering consistent coding standards and ideas for improvement. This will lessen the possibility of mistakes and facilitates efficient teamwork.\n- **Faster rollout and iteration.** AI-assisted code recommendations can hasten the deployment and iteration processes. With fewer errors and more effective code, developers can iterate and release updates faster. Code reviews also are faster and more efficient. As a result, enterprises can quickly bring new features to market, providing them with a substantial competitive edge.\n\n### GitLab’s competitive advantages\n\nGitLab’s unified DevSecOps platform enables businesses to deliver software more quickly and efficiently while enhancing security and compliance and maximizing the total return of investment on software development. We anticipate GitLab AI Assisted Code Suggestions will extend and amplify these benefits to improve developer productivity, focus, and innovation without context switching and within a single DevSecOps platform using the GitLab Workflow VS Code extension to get code suggestions as they type. Depending on the user prompts, the extension provides entire code snippets like generating functions or completing the current line. Simply pressing the tab key enables you to accept the suggestions.\n\nAs AI technologies advance in sophistication, they will provide more individualized and nuanced ideas, increasing their value to programmers.\n\nThe low-code/no-code development sectors are where AI-assisted code suggestions are anticipated to have substantial impact. As these development platforms spread, we envision bringing AI-powered tools that can offer recommendations and optimizations to simplify the software creation and deployment process for non-technical users on GitLab.com. \n\nThe following are some of the critical jobs we intend to address for our customers with AI Assisted Code Suggestions in the DevSecOps Platform:\n\n- **Code optimization.** How can we drastically reduce the time and effort required for developers to examine and test their code by identifying redundant or inefficient lines of code and suggesting streamlined alternatives?\n- **Automatic bug detection and patching.** How can we analyze sizable codebases to find potential bugs or security flaws and can also offer patches to fix them?\n- **Smart debugging.** How can we assist developers in locating faults precisely and make suggestions for potential fixes? This can result in considerable time and effort savings for developers and quicker bug response.\n- **Continuous integration and deployment.** How can we facilitate continuous integration and deployment by identifying code changes that could cause potential conflicts? This will enable developers to resolve issues quickly and roll out production code faster.\n- **Predictive maintenance.** How can we monitor the performance of the code and find potential issues before they become serious? As a result, developers may proactively address faults, leading to more dependable and stable software.\n- **Programming in natural language.** How can we allow developers to build code via simple natural-language commands? This can result in more efficient development and a much shorter learning curve for new developers.\n- **Test case generation and automation.** How can we generate test cases and automate the testing process? In addition to ensuring that software is adequately tested before it is deployed, this can cut down on the time and effort needed for testing.\n- **Smart code completion.** How can we ensure developers write code faster and more precisely, which completes code snippets based on context? This may lead to fewer mistakes and more effective development.\n\nGitLab’s AI Assisted Code Suggestions are available to select Ultimate customers in a closed beta. For early access consideration, Ultimate customers can [submit this form](https://docs.google.com/forms/d/e/1FAIpQLSdSixexFKnIkFGBbmx6XJfBdEBACowhsO-DOm82q4rrAAuYmA/viewform). We’re working towards a wider open beta of this capability in the next few months. \n\nContinue reading our ongoing series, \"[AI/ML in DevSecOps](/blog/ai-ml-in-devsecops-series/)\".\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[9,848,719,717],"product",{"slug":850,"featured":6,"template":698},"ai-assisted-code-suggestions","content:en-us:blog:ai-assisted-code-suggestions.yml","Ai Assisted Code Suggestions","en-us/blog/ai-assisted-code-suggestions.yml","en-us/blog/ai-assisted-code-suggestions",{"_path":856,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":857,"content":863,"config":869,"_id":871,"_type":14,"title":872,"_source":16,"_file":873,"_stem":874,"_extension":19},"/en-us/blog/announcing-gitlab-devsecops",{"title":858,"description":859,"ogTitle":858,"ogDescription":859,"noIndex":6,"ogImage":860,"ogUrl":861,"ogSiteName":686,"ogType":687,"canonicalUrls":861,"schema":862},"Announcing GitLab for DevSecOps","GitLab brings development, security, and operations into a single application.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749671668/Blog/Hero%20Images/integrated.jpg","https://about.gitlab.com/blog/announcing-gitlab-devsecops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Announcing GitLab for DevSecOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Erica Lindberg\"}],\n        \"datePublished\": \"2019-06-20\",\n      }",{"title":858,"description":859,"authors":864,"heroImage":860,"date":866,"body":867,"category":301,"tags":868},[865],"Erica Lindberg","2019-06-20","\n\n[DevOps](/topics/devops/) adoption continues to mature, and as organizations get better at breaking down silos in the development and delivery process to ship software faster, security is moving to the forefront. In fact, [Forrester predicted that 2019 would be the year of security](https://www.forrester.com/report/Predictions+2019+DevOps/-/E-RES144579): “Many organizations have succeeded in automating continuous release and deployment for some applications but face increasing risk from lack of governance and fragmented toolchains.”\n\n[DevSecOps](/topics/devsecops/) is the natural next iteration of DevOps and today we are excited to announce that we are bringing developers, operations professionals, and the security team together in the first single application for the entire DevSecOps lifecycle. Building upon the [security features](/pricing/feature-comparison/) we’ve added over the past 12 months (SAST, DAST, dependency scanning, and container scanning), we’ve also released Auto Remediation, Security Dashboards, and will release [Security Approvals](https://gitlab.com/gitlab-org/gitlab-ee/issues/9928) in 12.1, creating an application with security and compliance built in. Additionally, we’ve expanded our operations capabilities: In addition to our Kubernetes-native integrations and multicloud deployment support, we’ve added [Feature Flags](/direction/release/feature_flags/), an [Operations Dashboard](https://docs.gitlab.com/ee/user/operations_dashboard/), and will release [Incident Management](/direction/service_management/incident_management/) in 12.1.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/zRUwU6ZE-QA\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nWith GitLab 12.0, releasing on June 22, we continue to support DevSecOps with the addition of Visual Review Tools, project dependency list, and Merge Trains. As our CEO, [Sid Sijbrandij](/company/team/#sytses), says, “GitLab 12.0 marks a key step in our journey to create an inclusive approach to DevSecOps.” And users are already seeing the benefits:\n\n“We already have a frontend team, an SDK and native app team, an SRE team, and a services team all collaborating on development, security, and operations in GitLab,” said Cillian Dwyer, site reliability engineer, Glympse. “Because we're together, we're able to collaborate and ship faster.”\n\n“As a project, we’re excited to see all of the updates GitLab has made. GitLab makes it easy for us to work on community contributions and CI in general,” said Eduardo Silva, maintainer of [Fluent Bit](https://fluentbit.io/) (a Fluentd sub-project), the cloud native, open source logging solution to unify data collection and consumption.\n\n## DevSecOps in a single application\n\nThe [advantages of a single application](/handbook/product/single-application/) are numerous: A single sign-on eliminates the need to request access to each separate tool, context switching is reduced which improves cycle time, and work is tracked in one place so you don’t have to do detective work to find the information you need. According to Forrester’s [Manage Your Toolchain Before It Manages You report](/resources/whitepaper-forrester-manage-your-toolchain/), over 40% of enterprises anticipate improved quality, security, and developer productivity by using an out-of-the-box solution. For security professionals, this means that balancing velocity with security is possible.\n\nSecurity has traditionally been the “final hurdle” in the development lifecycle, tacked on at the end and often reviewed long after the developer committed their code. When security is separate from the DevOps workflow, it becomes a potential bottleneck to delivery. DevSecOps aims to integrate security best practices in the DevOps workflow to ensure every piece of code is tested upon commit. GitLab takes that a step further by building [security capabilities](/direction/secure/#auto-remediation) into the [CI/CD workflow](/topics/ci-cd/), empowering developers to identify vulnerabilities and remove them early, and by providing the security team with their own dashboard to view items not resolved by the developers.\n\n![GitLab DevSecOps diagram](https://about.gitlab.com/images/secure/security-diagram.svg){: .medium.center}\n\nGitLab integrates and automates security into the CI/CD pipeline.\n{: .note.text-center}\n\nThe approach is to support decision makers with actionable tools that make it simpler to take the right action and learn from it. Instead of security features automatically blocking a pipeline or preventing a new version from being released to production, users can interact with the tool and perform a risk assessment based on the information provided. When triaging vulnerabilities, users can confirm by creating an issue to solve the problem or dismiss them in the case of false positives.\n\n### Secure features in GitLab\n\nWe started our DevSecOps journey by empowering developers to spot potential vulnerabilities while coding by embedding [Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) and [Dynamic Application Security Testing (DAST)](https://docs.gitlab.com/ee/user/application_security/dast/), [Container Scanning](https://docs.gitlab.com/ee/user/application_security/container_scanning/), and [Dependency Scanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/) into the CI/CD pipeline.\n\n![GitLab static application security testing feature](https://about.gitlab.com/images/secure/sast.png){: .shadow.medium.center}\n\nDetected vulnerabilities are shown directly in the merge request.\n{: .note.text-center}\n\nSAST scans the application source code and binaries to spot potential vulnerabilities before deployment, and DAST analyzes your running web application for runtime vulnerabilities and runs live attacks against the review app. Information is shown directly in the merge request and results are sorted by the priority of the vulnerability.\n\nLikewise, Dependency Scanning and Container Scanning are built into GitLab CI/CD and available as part of [Auto DevOps](https://docs.gitlab.com/ee/topics/autodevops/) to provide security by default. Container Scanning runs a security scan to ensure your environment does not have any known vulnerability. Dependency scanning analyzes external dependencies (e.g. Ruby gem libraries), alerting the developer if vulnerable dependencies need updating. Results are shown in both the merge request and pipeline views.\n\n> “Having automated security scans built into GitLab merge requests spanning across the entire DevOps lifecycle go together perfectly with Rancher and K3s. Our joint customers have more confidence that new vulnerabilities are not being introduced into their code before, during and after deployment.” - Shannon Williams, co-founder at Rancher\n\nThe next iteration of our security journey included making GitLab a viable product for the security team by automating what can be automated and ensuring security teams have the view they need to understand the current security status of their applications.\n\n![GitLab Security Dashboard](https://about.gitlab.com/images/secure/security-dashboard.png){: .shadow.medium.center}\nThe group-level Security Dashboard in GitLab gives an overview of vulnerabilities for all projects within the group and sub-groups.\n{: .note.text-center}\n\nThe [Security Dashboard](https://docs.gitlab.com/ee/user/application_security/security_dashboard/) is available at both the group and product level and can be used as a primary tool for security teams. In addition to providing an overview of security status, the Security Dashboard can be used to start a remediation process and provides data visualizations for easy consumption of performance information.\n\nFinally, we are rapidly iterating on Auto Remediation to automate vulnerability fixes. Auto Remediation aims to automate vulnerability solution flow, and automatically create a fix. The fix is then tested, and if it passes all the tests already defined for the application, it is deployed to production. GitLab can then monitor performances of the deployed app, and revert all the changes in case performances are decreasing dramatically, warning the user about the entire process and reducing the need for manual actions. You can [learn more about Auto Remediation and our progress here](https://gitlab.com/groups/gitlab-org/-/epics/759).\n\n> \"By adding automated security processes into code delivery, GitLab is furthering productivity by allowing organizations to focus on getting their applications to market not only quickly but securely. We look forward to continuing to work with GitLab as they build out more capabilities in their application, and help companies using GitLab further their multicloud strategy.\" - Bassam Tabbara, CEO of Upbound\n\nOverall, with security automated throughout the developer workflow and DevSecOps delivered in a single application, we believe companies will continue to advance the way they deliver code, shortening release cycles and focusing on the innovation they will bring to market. For more information on what shipped with 12.0, watch out for the release post on June 22.\n\nCover image by [Katie Burkhart](https://unsplash.com/@katieanalyzes) on [Unsplash](https://unsplash.com/photos/ks_e5Rf-Cn0)\n{: .note}\n",[550,9],{"slug":870,"featured":6,"template":698},"announcing-gitlab-devsecops","content:en-us:blog:announcing-gitlab-devsecops.yml","Announcing Gitlab Devsecops","en-us/blog/announcing-gitlab-devsecops.yml","en-us/blog/announcing-gitlab-devsecops",{"_path":876,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":877,"content":883,"config":890,"_id":892,"_type":14,"title":893,"_source":16,"_file":894,"_stem":895,"_extension":19},"/en-us/blog/atlassian-server-ending-move-to-a-single-devsecops-platform",{"title":878,"description":879,"ogTitle":878,"ogDescription":879,"noIndex":6,"ogImage":880,"ogUrl":881,"ogSiteName":686,"ogType":687,"canonicalUrls":881,"schema":882},"Atlassian Server ends: Time to move to integrated DevSecOps","Atlassian is about to end support for Server products. Learn why now is the time to make the upgrade to GitLab’s single DevSecOps platform.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749658924/Blog/Hero%20Images/securitylifecycle-light.png","https://about.gitlab.com/blog/atlassian-server-ending-move-to-a-single-devsecops-platform","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Atlassian Server ending: Goodbye disjointed toolchain, hello DevSecOps platform\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Dave Steer\"}],\n        \"datePublished\": \"2023-09-26\",\n      }",{"title":884,"description":879,"authors":885,"heroImage":880,"date":887,"body":888,"category":10,"tags":889},"Atlassian Server ending: Goodbye disjointed toolchain, hello DevSecOps platform",[886],"Dave Steer","2023-09-26","\nThe February 15, 2024, end-of-life date for Atlassian Server is fast approaching. If your software development workflows rely on on-premises deployments of Atlassian Server products such as Bitbucket Server for source code management, Bamboo Server for CI/CD, or Jira Server for Agile Planning, you’re faced with a choice. You can settle for the Atlassian options that remain available to you, or you can take a more forward-looking path: Make the move to a single AI-powered DevSecOps platform.\n\n## Atlassian Server end of life: Migration made easy\nMigrating to a DevSecOps platform is simple: With GitLab’s various importer tools you can quickly import repositories, Jira issues, and Bamboo jobs. Here are a few resources you can use to get started, whether you’re ready to adopt the whole GitLab platform or you’d like to move one service at a time:\n* [Import your project from Bitbucket Cloud to GitLab](https://docs.gitlab.com/ee/user/project/import/bitbucket.html)\n* [Import your project from Bitbucket Server to GitLab](https://docs.gitlab.com/ee/user/project/import/bitbucket_server.html)\n* [Import your Jira project issues to GitLab](https://docs.gitlab.com/ee/user/project/import/jira.html)\n* [Integrate Jira with GitLab](https://docs.gitlab.com/ee/integration/jira/)\n\nAtlassian discontinuing Server presents the perfect opportunity to consolidate your toolchain, increase developer efficiency, and implement DevSecOps. Let’s take a look at the benefits you can expect from making this move.\n\n## Less complexity, more productivity\nDevSecOps enables companies to build software faster, more efficiently, and more securely. At the same time, the proliferation of DevOps tools is creating additional complexity in how companies develop, secure, and deploy software, which in turn is costing companies time and money. GitLab’s [2023 Global DevSecOps Survey](https://about.gitlab.com/developer-survey/) found that 84% of organizations are using between two and ten DevOps tools, with 69% of developers spending at least a quarter of their time maintaining and integrating toolchains. Even if some of those various DevOps tools are from the same vendor, they often require work in the background to set up, secure, and maintain the integrations. That’s a significant amount of effort that teams could be using to deliver value to customers.\n\nLet’s say you’re an Atlassian shop. You’re using Bitbucket Server for source code management, Bamboo Server for CI/CD, Zephyr for test case management, Jira Server for agile planning, and numerous other third-party tools for security scanning, vulnerability tracking, and more. As the Atlassian Server end of life approaches, you know that continuing to use Server without security updates and vulnerability fixes puts your company and customers at risk — a major no-go for security and compliance reasons. You have the option to move to Atlassian Cloud or, if you need to remain on-premises, Atlassian Data Center. But transitioning requires time, effort, and significant planning. If you’re already dedicating resources to making this change, why not take the opportunity to simplify matters by consolidating all of those tools into a single [AI-powered DevSecOps platform](https://about.gitlab.com/blog/categories/ai-ml/) instead?\n\nAccording to our 2023 survey, the top benefits of migrating to a DevSecOps platform include cost and time savings, increased efficiency, and better security. Plus, 90% of developers whose organizations are using a platform said they feel they’re able to effectively identify and mitigate security vulnerabilities, among other benefits.\n\n> How much is your toolchain costing you? [See how much you can save with the GitLab DevSecOps Platform](https://about.gitlab.com/calculator/roi/).\n\n## Improved developer experience\nTime spent maintaining and integrating toolchains isn’t just money down the drain for the organization — it’s also a drain on developer satisfaction. [Helping organizations better support their developers](https://about.gitlab.com/blog/the-gitlab-quarterly-how-our-latest-beta-releases-support-developers/) has always been a priority for GitLab, and we’re confident in our position that a single DevSecOps platform is the best way to do just that.\n\nWith a single platform, developers stay in flow and do what they do best: develop great software. More concretely, a superior developer experience empowers teams to:\n* focus on work that matters, with less context switching between different tools\n* onboard and get up to speed more quickly with only a single platform to learn\n* break down silos across product, development, security, and operations to foster better collaboration\n* receive continuous feedback and iterate more quickly to produce higher-quality output\n* automate manual tasks with AI built into the development lifecycle to avoid errors and wasted time\n\nIf your team hasn’t been able to invest in the developer experience, now is the perfect time to make it a priority. We’ve heard from GitLab customers like [Airbus](https://about.gitlab.com/customers/airbus/) and [Iron Mountain](https://about.gitlab.com/customers/iron-mountain/) that a toolchain consisting of Jira, Bitbucket, and Bamboo doesn’t offer a user-friendly experience and lacks key capabilities. Why migrate to a new Atlassian Cloud or Data Center setup if you’re going to be missing out on mission-critical features such as [built-in security scanning](https://docs.gitlab.com/ee/user/application_security/), [review apps](https://docs.gitlab.com/ee/ci/review_apps/), and [feature flags](https://docs.gitlab.com/ee/operations/feature_flags.html)?\n\n## Visibility at every stage\nA unified DevSecOps platform offers [out-of-the-box dashboards and reports](https://about.gitlab.com/blog/getting-started-with-value-streams-dashboard/) that provide insights on productivity, security, code quality, and more to help teams identify and fix barriers within the software development lifecycle. In our 2023 survey, respondents whose organizations are using a DevSecOps platform were significantly more likely to say they clearly understand what is happening across all stages of the software development lifecycle.\n\nHaving that extra visibility:\n* improves software delivery quality and speed by uncovering bottlenecks in software delivery\n* boosts organizational value delivery by helping organizations identify high-performing teams, maintain standards, and share best practices\n* helps organizations ensure the security of their end-to-end software supply chain and compliance with regulatory mandates\n\nYou can’t get that visibility without a single DevSecOps platform — and GitLab is the most comprehensive AI-powered DevSecOps platform on the market. With other providers, you’re still stringing together various third-party tools into complex toolchains, hampering visibility while creating integration headaches and increasing your total cost of ownership. From idea to value, GitLab lets teams collaborate in a single application to [shorten cycle times](https://about.gitlab.com/customers/hackerone/), [reduce development costs](https://about.gitlab.com/customers/carfax/), and [increase developer productivity](https://about.gitlab.com/customers/deutsche-telekom/).\n\n> Learn why GitLab was named a [Leader in the 2023 Gartner® Magic Quadrant™ for DevOps Platforms](https://about.gitlab.com/gartner-magic-quadrant/).\n\nBottom line: [With Atlassian Server support ending](https://www.atlassian.com/migration/assess/journey-to-cloud), you shouldn’t be forced to choose an option that isn’t right for the [future of your business](https://about.gitlab.com/blog/devsecops-platforms-help-smbs-scale-as-they-grow/). Whether you’re on the lookout for alternatives to fundamental tools in your stack that will no longer be supported, or you’re simply seeking new ways to boost the productivity of your growing team, adopting an AI-powered DevSecOps platform should be as frictionless as possible. That’s why GitLab offers a variety of deployment options to meet your unique needs, including self-managed, multi-tenant SaaS, and [GitLab Dedicated, our single-tenant SaaS offering](https://about.gitlab.com/blog/introducing-gitlab-dedicated/).\n\nWhen you’re ready to make the move, [we’re here to help](https://about.gitlab.com/sales/).\n",[9,109,694],{"slug":891,"featured":6,"template":698},"atlassian-server-ending-move-to-a-single-devsecops-platform","content:en-us:blog:atlassian-server-ending-move-to-a-single-devsecops-platform.yml","Atlassian Server Ending Move To A Single Devsecops Platform","en-us/blog/atlassian-server-ending-move-to-a-single-devsecops-platform.yml","en-us/blog/atlassian-server-ending-move-to-a-single-devsecops-platform",{"_path":897,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":898,"content":904,"config":911,"_id":913,"_type":14,"title":914,"_source":16,"_file":915,"_stem":916,"_extension":19},"/en-us/blog/automating-a-twitter-bot-using-gitlab-cicd",{"title":899,"description":900,"ogTitle":899,"ogDescription":900,"noIndex":6,"ogImage":901,"ogUrl":902,"ogSiteName":686,"ogType":687,"canonicalUrls":902,"schema":903},"How to automate a Twitter bot using GitLab CI/CD","This tutorial shows how to use the DevSecOps platform to create a set-and-forget Twitter bot.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749661856/Blog/Hero%20Images/ci-cd-demo.jpg","https://about.gitlab.com/blog/automating-a-twitter-bot-using-gitlab-cicd","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to automate a Twitter bot using GitLab CI/CD\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Siddharth Mathur\"}],\n        \"datePublished\": \"2023-03-21\",\n      }",{"title":899,"description":900,"authors":905,"heroImage":901,"date":907,"body":908,"category":909,"tags":910},[906],"Siddharth Mathur","2023-03-21","\n\nGitLab's CI/CD pipelines are great for automating many things, like deployments to Google Kubernetes Engine and security scans. But did you know that you could use GitLab CI/CD pipelines to run a set-and-forget Twitter bot?\n\nMany organizations today are leveraging Twitter's API to [understand customer sentiment](https://developer.twitter.com/en/blog/success-stories/target), [track public health data](https://developer.twitter.com/en/blog/success-stories/penn), [perform financial analysis](https://developer.twitter.com/en/blog/success-stories/likefolio), and more. While these bots may be running on self-managed infrastrucuture or external services, you can simplify and consolidate your tooling by leveraging GitLab instead, making your bot easier to manage.\n\nWith GitLab's [Free tier](/pricing/), you can leverage 400 minutes of CI/CD run time per month to automatically analyze and post tweets. With GitLab [Premium](/pricing/premium) and [Ultimate](/pricing/ultimate), you'll get even more pipeline minutes to tweet more, run longer natural language processing analyses, or for other projects.\n\nSetting up a Twitter bot using GitLab is pretty simple. At the end of this blog, you'll have a project that looks like [this](https://gitlab.com/smathur/twitter-bot), and a Twitter account that automatically posts a simple tweet.\n\nTo get started, you'll need these prerequisites:\n- GitLab account (self-hosted with GitLab Runner(s) set up or on GitLab.com)\n- Twitter API credentials\n\nOnce you've generated your Twitter API credentials, we can start building out our bot in GitLab. In this blog, we'll leverage GitLab's Web IDE based on Visual Studio Code, but feel free to use a code editor of your choice.\n\n## Step 1: Write a Python script to post tweets\n\n![Navigate to the Web IDE](https://about.gitlab.com/images/blogimages/2023-03-10-automating-a-twitter-bot-using-gitlab-cicd/web-ide.png){: .shadow}\n\nCreate a new blank project in GitLab, and click the \"Web IDE\" button to start writing some code. In the Web IDE, create a new file called `run_bot.py`, and paste the following code (this is where you interact with the Twitter API):\n\n```python\nimport tweepy\nimport config\n\ndef set_up():\n\tauth = tweepy.OAuthHandler(config.consumer_key, config.consumer_secret_key)\n\tauth.set_access_token(config.access_token, config.access_token_secret)\n\tapi = tweepy.API(auth)\n\treturn api\n\ndef run(tweet):\n\tapi = set_up()\n\tapi.update_status(tweet)\n\nrun('It\\'s Tanuki time')\n```\n\n**Note:** If you're familiar with Python, you'll notice that we're importing a file called `config` with some variables that we're using. This `config` file doesn't exist yet, but we'll create it from within a GitLab pipeline, leveraging CI/CD variables to securely store and use our Twitter API credentials.\n\nCreate another file called `requirements.txt`, and paste the following line:\n\n```\ntweepy\n```\n\nChanges to files in the Web IDE will be automatically saved, so switch to the Git tab and commit your changes.\n\n## Step 2: Create a CI/CD pipeline to run your Python script\n\nNext, we'll create a CI/CD pipeline script to run our Twitter bot and post a tweet every time the pipeline is run. To do this, you can:\n1. Create a new file using the Web IDE called `.gitlab-ci.yml`, or\n2. Head to your GitLab project, and from the sidebar, click CI/CD > Editor.\n\nIf you see some default text in the pipeline configuration, delete everything to start with a clean slate.\n\nIn the pipeline YAML file, we'll first specify the Docker image we want to run the bot on:\n\n```yaml\nimage: python:latest\n```\n\n**Note:** Normally in a pipeline, we would define stages first and then write jobs that are each assigned to a specific stage. Since we're only running one job in this pipeline, we don't need to specify stages at the top of our pipeline configuration file.\n\nNext, we'll add a job called `run` that runs the Python script we created in the previous step. Inside this job, we'll add a `script` section to run some commands that will execute our Python script.\n\n```yaml\nrun:\n  script:\n    - echo \"consumer_key = '$CONSUMER_KEY'\" >> config.py\n    - echo \"consumer_secret_key = '$CONSUMER_SECRET'\" >> config.py\n    - echo \"access_token = '$ACCESS_TOKEN'\" >> config.py\n    - echo \"access_token_secret = '$ACCESS_SECRET'\" >> config.py\n    - pip install -r requirements.txt\n    - python3 run_bot.py\n```\n\nCommit your changes. The pipeline will automatically run, since you just made a change to the project files, but it will fail. This is because we are calling some CI/CD variables in the pipeline, which we haven't set yet. Let's go ahead and do that!\n\n## Step 3: Set CI/CD variables to store API tokens\n\nHead to your GitLab project and from the sidebar, go to Settings > CI/CD.\n\nExpand the \"Variables\" section and add the `ACCESS_SECRET`, `ACCESS_TOKEN`, `CONSUMER_KEY`, and `CONSUMER_SECRET` variables as shown below (these are your Twitter API credentials):\n\n![CI/CD variables](https://about.gitlab.com/images/blogimages/2023-03-10-automating-a-twitter-bot-using-gitlab-cicd/ci-cd-variables.png){: .shadow}\n\nNote that the secrets are masked to prevent them from showing up in job logs (check the \"Mask variable\" box when creating/editing the variable).\n\n## Step 4: Test and schedule your Twitter bot\n\nNow that we've got everything set up, all we need to do is run the bot. Go to CI/CD > Pipelines, and click \"Run pipeline\". Click \"Run pipeline\" again, and wait for the `run` job to finish. If you've set up your Twitter credentials correctly, you should see that the pipeline successfully ran, and a tweet was posted on your bot account!\n\n![Schedule a pipeline](https://about.gitlab.com/images/blogimages/2023-03-10-automating-a-twitter-bot-using-gitlab-cicd/schedule-pipeline.png){: .shadow}\n\nOnce you've verified that your pipeline runs successfully, schedule your pipeline to automatically run at a regular interval. Go to CI/CD > Schedules, and click \"New schedule\". Feel free to use one of the default provided intervals, or use cron to set a custom schedule. Specify a timezone, and ensure that the \"Active\" checkbox is checked. Finally, click \"Save pipeline schedule\". You'll see that your pipeline has been scheduled to run, and when it will run next.\n\nAnd that's it! You now have a fully-functional Twitter bot running on GitLab, using CI/CD pipelines to automatically post tweets. While this demo Twitter bot simply posts a specified text message, you can add your own logic to [generate sentences using AI](https://linguatools.org/language-apis/sentence-generating-api/), [perform sentiment analysis on other users' tweets](https://www.analyticsvidhya.com/blog/2021/06/twitter-sentiment-analysis-a-nlp-use-case-for-beginners/), and more. Running a Twitter bot is just one of the many ways you can leverage pipelines in GitLab, and you can also check out some other [interesting use cases](https://docs.gitlab.com/ee/ci/examples/).\n","engineering",[9,825,826,827],{"slug":912,"featured":6,"template":698},"automating-a-twitter-bot-using-gitlab-cicd","content:en-us:blog:automating-a-twitter-bot-using-gitlab-cicd.yml","Automating A Twitter Bot Using Gitlab Cicd","en-us/blog/automating-a-twitter-bot-using-gitlab-cicd.yml","en-us/blog/automating-a-twitter-bot-using-gitlab-cicd",{"_path":918,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":919,"content":925,"config":931,"_id":933,"_type":14,"title":934,"_source":16,"_file":935,"_stem":936,"_extension":19},"/en-us/blog/automating-cybersecurity-threat-detections-with-gitlab-ci-cd",{"title":920,"description":921,"ogTitle":920,"ogDescription":921,"noIndex":6,"ogImage":922,"ogUrl":923,"ogSiteName":686,"ogType":687,"canonicalUrls":923,"schema":924},"Automating cybersecurity threat detections with GitLab CI/CD","Discover how GUARD automates cybersecurity threat detections through the use\nof GitLab CI/CD and how it ensures high-quality detections.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663239/Blog/Hero%20Images/AdobeStock_1023776629.jpg","https://about.gitlab.com/blog/automating-cybersecurity-threat-detections-with-gitlab-ci-cd","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Automating cybersecurity threat detections with GitLab CI/CD\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Mitra Jozenazemian\"}],\n        \"datePublished\": \"2025-01-29\",\n      }",{"title":920,"description":921,"authors":926,"heroImage":922,"date":928,"body":929,"category":694,"tags":930},[927],"Mitra Jozenazemian","2025-01-29","*This blog post is the second post in a series about [GitLab Universal\nAutomated Response and Detection\n(GUARD)](https://about.gitlab.com/blog/unveiling-the-guard-framework-to-automate-security-detections-at-gitlab/).*\n\n\nWriting and deploying security threat detections in an organization’s\nsecurity information event management platform (SIEM) is a critical\ncomponent of a successful cybersecurity program. Moving from manual\ndetection engineering to a fully automated process by implementing\nDetections as Code (DaC) ensures detection consistency, quality, auditing,\nand automated testing. At GitLab, we’ve embedded DaC capabilities into\nGUARD, our fully automated detection and response framework. \n\n\n## The problem: Source control and automated tests\n\n\nThe [Signals\nEngineering](https://handbook.gitlab.com/handbook/security/security-operations/signals-engineering/)\nand\n[SIRT](https://handbook.gitlab.com/handbook/security/security-operations/sirt/)\nteam at GitLab share the responsibility to create, update, and decommission\nthreat detections in our SIEM. Maintaining a single source of truth for\ndetections is critical to ensure detection consistency and quality standards\nare met. Our teams made the conscious decision to abstract the detection\ncreation process from our SIEM, improving our issue tracking, consistency,\nroll-back process, and metrics. Additionally, conducting pre-commit\ndetection tests outside of our SIEM ensured that newly created detections\ndidn’t introduce overly false positive heavy alerts, which would require\ntuning or disablement while the alert was fixed. \n\n\n## The Solution: Leverage GitLab CI/CD for detection testing and validation\n\n\nTo address these challenges, we developed an efficient workflow using GitLab\n[CI/CD](https://about.gitlab.com/topics/ci-cd/), resulting in a streamlined\nand secure SIEM detection deployment process.\n\n\n### Key components of the GUARD DaC pipeline \n\n\n__1. Detections stored in JSON format in a GitLab project__\n\n\nGitLab uses the JSON format for our threat detections. The template includes\nessential information such as SIEM query logic, detection title, and\ndescription along with runbook page link, MITRE tactic and technique related\nto the detection, and other necessary details.\n\n\n__2. Initiating merge requests__\n\n\nWhen a GitLab team member intends to create a new threat detection, update\nan existing one, or delete a current detection, they initiate the process by\nsubmitting a merge request (MR) in the DaC project containing the detection\nJSON template. Creating the MR automatically triggers a CI/CD pipeline.\n\n\n__3. Automated validation with CI/CD jobs__\n\n\nEach MR contains a number of automated checks via GitLab CI/CD:   \n\n* Query format validation queries SIEM API to ensure detection query is\nvalid  \n\n* JSON Detection fields validation validates all required fields are\npresent, and are in the correct format   \n\n* New detections and detection modification trigger a number of SIEM API\ncalls to ensure the detection does not have any errors and that no issues\nwill be introduced into our production detection rules   \n\n* Detection deletion MRs trigger the pipeline to issue a SIEM API query to\nensure the detection to be deleted is still active and can be deleted \n\n\n__4. Peer review and approval__\n\n\nWhen a detection MR job completes successfully, a peer review is required to\nreview and confirm the MR meets required quality and content standards\nbefore the detection MR can be merged. [Merge request approval\nrules](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/rules.html)\nare used to trigger the peer review process. \n\n\n__5. Merge and final deployment__\n\n\nAfter the MR is approved, it is merged into the main branch. As part of the\nCI/CD pipeline, an automated job executes a SIEM API command in order to\nperform two tasks:   \n\n* Create the new detection or update/delete the existing detection if\nneeded.   \n\n* Extract the MITRE ATT&CK tactic and technique information related to the\nalert from the JSON files and transmit these details to a lookup table\nwithin the SIEM. This lookup table plays an important role in mapping our\nalerts to MITRE tactics and techniques, helping us improve our threat\nanalysis and identify gaps in our detection capabilities in alignment with\nthe MITRE framework.\n\n\n**Note:** The necessary credentials for these actions are securely stored in\n[CI/CD variables](https://docs.gitlab.com/ee/ci/variables/) to ensure the\nprocess remains confidential and secure.\n\n\nBelow is a template GitLab CI/CD `gitlab-ci.yml` configuration file for a\nDaC pipeline: \n\n\n```\n\n\n#\n---------------------------------------------------------------------------\n#\n\n# GitLab CI/CD Pipeline for SIEM Detection Management\n\n#\n---------------------------------------------------------------------------\n#\n\n\nimage: python:3.12\n\n\n#\n---------------------------------------------------------------------------\n#\n\n# Global Configuration\n\n#\n---------------------------------------------------------------------------\n#\n\n\nbefore_script:\n  - apt-get update && apt-get install -y jq\n  - pip install --upgrade pip\n  - pip install -r requirements.txt\n\n#\n---------------------------------------------------------------------------\n#\n\n\nstages:\n  - fetch\n  - test\n  - process\n  - upload\n\n#\n---------------------------------------------------------------------------\n#\n\n# Fetch Stage\n\n#\n---------------------------------------------------------------------------\n#\n\n\nfetch_changed_files:\n  stage: fetch\n  Script:\n    - echo \"Fetching changed files...\"\n    - git branch\n    - git fetch origin $CI_DEFAULT_BRANCH:$CI_DEFAULT_BRANCH --depth 2000\n    - |\n      if [[ \"$CI_COMMIT_BRANCH\" == \"$CI_DEFAULT_BRANCH\" ]]; then\n        git diff --name-status HEAD^1...HEAD > changed-files-temp.txt\n      else\n        git fetch origin $CI_COMMIT_BRANCH:$CI_COMMIT_BRANCH --depth 2000\n        git diff --name-status ${CI_DEFAULT_BRANCH}...${CI_COMMIT_SHA} > changed-files-temp.txt\n      fi\n    - grep -E '\\.json$' changed-files-temp.txt > changed-files.txt || true\n    - flake8 .\n    - pytest\n  artifacts:\n    paths:\n      - changed-files.txt\n    expose_as: 'changed_files'\n\n#\n---------------------------------------------------------------------------\n#\n\n# Test Stage\n\n#\n---------------------------------------------------------------------------\n#\n\n\nflake8:\n  stage: test\n  script:\n    - echo \"Running Flake8 for linting...\"\n    - flake8 .\n\npytest:\n  stage: test\n  script:\n    - echo \"Running Pytest for unit tests...\"\n    - pytest\n  artifacts:\n    when: always\n    reports:\n      junit: report.xml\n\n#\n---------------------------------------------------------------------------\n#\n\n# Process Stage\n\n#\n---------------------------------------------------------------------------\n#\n\n\nprocess_files:\n  stage: process\n  script:\n    - echo \"Processing changed files...\"\n    - git clone --depth 2000 --branch $CI_DEFAULT_BRANCH $CI_REPOSITORY_URL\n    - mkdir -p modified_rules delete_file new_file\n    - python3 move-files.py -x changed-files.txt\n    - python3 check-alerts-format.py\n  artifacts:\n    paths:\n      - modified_rules\n      - delete_file\n      - new_file\n#\n---------------------------------------------------------------------------\n#\n\n# Upload Stage\n\n#\n---------------------------------------------------------------------------\n#\n\n\nupdate_rules:\n  stage: upload\n  script:\n    - echo \"Uploading updated rules and lookup tables...\"\n    - git fetch origin $CI_DEFAULT_BRANCH:$CI_DEFAULT_BRANCH --depth 2000\n    - git clone --depth 2000 --branch $CI_DEFAULT_BRANCH $CI_REPOSITORY_URL \n    - python3 update-rules.py\n    - python3 update-exceptions.py\n    - python3 create_ttps_layers.py\n  rules:\n    - if: $CI_COMMIT_BRANCH == \"main\" && $CI_PIPELINE_SOURCE != \"schedule\"\n      changes:\n        - detections/**/*\n        - exceptions/**/*\n```\n\n\nThe diagram below illustrates the workflow of the CI/CD process described\nabove.\n\n\n```mermaid\n\ngraph TD;\n    fetch[Fetch Stage: Identify Changed Files] --> test[Test Stage: Run Linting and Tests];\n    test --> process[Process Stage: Categorize Files];\n    process --> upload[Upload Stage: Update Rules and Lookup Tables];\n    fetch --> fetch_details[Details: Filter JSON files, Output 'changed-files.txt'];\n    test --> test_details[Details: Run Flake8 for linting, Pytest for testing];\n    process --> process_details[Details: Categorize into 'modified', 'new', 'deleted', Prepare for upload];\n    upload --> upload_details[Details: Update repo, Update detections in SIEM and SIEM lookup table];\n```\n\n\n## Benefits and outcomes\n\n\nAutomating our detections lifecycle through a DaC CI/CD-powered workflow\nintroduces numerous benefits to our threat detection deployment process:\n\n\n* Automation: Automating the creation and validation of SIEM detections\nreduces manual errors and saves time.\n\n* Enhanced security: The CI-driven workflow enforces a \"least privilege\"\npolicy, ensuring consistency, peer reviews, and quality standards for\ncreating, updating, or deleting threat detections. \n\n* Efficiency: The standardized JSON detection format and automated creation\nexpedite the deployment process.\n\n* Collaboration: The MR and review process fosters collaboration and\nknowledge sharing among GitLab team members.\n\n* Version control: Treating threat detection as code abstracts the\ndetections from the SIEM platform they are ultimately stored in. This\nabstraction provides a historical record of changes, facilitates\ncollaboration, and enables rollbacks to previous configurations if issues\narise.\n\n\n## Get started with DaC\n\n\nUsing GitLab CI/CD and a \"least privilege\" policy has made our SIEM\ndetection and alert management easier and more secure. Automation has\nimproved efficiency and reduced risks, providing a helpful example for\nothers wanting to improve their security and compliance. You can try this\ntutorial by signing up for a [free trial of GitLab\nUltimate](https://about.gitlab.com/free-trial/).",[694,827,9,496,109],{"slug":932,"featured":6,"template":698},"automating-cybersecurity-threat-detections-with-gitlab-ci-cd","content:en-us:blog:automating-cybersecurity-threat-detections-with-gitlab-ci-cd.yml","Automating Cybersecurity Threat Detections With Gitlab Ci Cd","en-us/blog/automating-cybersecurity-threat-detections-with-gitlab-ci-cd.yml","en-us/blog/automating-cybersecurity-threat-detections-with-gitlab-ci-cd",{"_path":938,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":939,"content":945,"config":954,"_id":956,"_type":14,"title":957,"_source":16,"_file":958,"_stem":959,"_extension":19},"/en-us/blog/best-practices-leading-orgs-to-release-software-faster",{"title":940,"description":941,"ogTitle":940,"ogDescription":941,"noIndex":6,"ogImage":942,"ogUrl":943,"ogSiteName":686,"ogType":687,"canonicalUrls":943,"schema":944},"4 best practices leading orgs to release software faster","GitLab's 2023 Global DevSecOps Survey illuminates the strategies that organizations deploying more frequently have in common.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663908/Blog/Hero%20Images/2023-devsecops-report-blog-banner2.png","https://about.gitlab.com/blog/best-practices-leading-orgs-to-release-software-faster","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"4 best practices leading orgs to release software faster\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kristina Weis\"}],\n        \"datePublished\": \"2023-06-08\",\n      }",{"title":940,"description":941,"authors":946,"heroImage":942,"date":948,"body":949,"category":950,"tags":951},[947],"Kristina Weis","2023-06-08","\nReleasing software faster is one of the biggest goals of many organizations — and for good reason. It helps them keep up with competitors, land and keep more customers, improve employee satisfaction, and much more. But maintaining that velocity requires investment in processes and technologies that help DevSecOps teams deliver, secure, and deploy software faster without compromising quality.\n\nIn our [2023 Global DevSecOps Survey](https://about.gitlab.com/developer-survey/) we asked more than 5,000 development, security, and operations professionals about everything from deployment frequency to the practices teams have adopted – all to learn what the most agile and efficient organizations have in common. One respondent, a director of IT security in the retail sector, summed up the challenge as follows: “Software customers are increasingly vocal and demanding, expecting faster releases and greater customizability. Developers will need to keep up with these demands while still maintaining stability and usability.”\n\nSo what’s helping organizations be more productive and efficient? Here are four of the best practices that, according to the survey, help organizations release software faster and deploy more frequently:\n\n## 1. Running applications in the cloud\nOne of the benefits people commonly attribute to deploying to the cloud is increased development speed. As it turns out, this year’s survey shows there’s some serious truth to that. Respondents with at least a quarter of their applications in the cloud were 2.2 times more likely to be releasing software faster than they were a year ago — and respondents with at least half of their applications in the cloud were 4.2 times more likely to deploy to production multiple times per day.\n\nSeveral respondents commented on the value of the cloud while also acknowledging the complexities cloud computing can bring to software development. An IT operations manager in the industrial manufacturing sector shared that “developing software that is designed for the cloud-native environment” is one of the top challenges facing software development this year. Likewise, an IT operations manager in the telecommunications sector said: “With the increase in the use of cloud computing and IoT devices, there is a greater need for secure coding practices to protect sensitive data from cyber attacks.” As organizations move to a cloud-first model for software development, they will need to adopt technologies that allow them to build natively in the cloud while keeping security top of mind throughout the development process.\n\n## 2. BizDevOps\nThough DevOps and DevSecOps mostly steal the show in terms of methodologies, some organizations go a step further and [practice BizDevOps](https://about.gitlab.com/blog/a-snapshot-of-modern-devops-practices-today/) — that is, incorporating business teams alongside development, security, and operations teams. An IT operations manager in the software sector emphasized the importance of collaboration with the business, sharing that “as software projects become larger and more complex, developers will need to work closely with other team members, including designers, testers, project managers, and business stakeholders.” This approach appears to be paying off for some: Respondents whose organizations practice BizDevOps were 1.4 times more likely to be releasing software faster than they were a year ago.\n\n## 3. CI/CD\nIt’s not surprising that automating the software development lifecycle with [CI/CD](https://docs.gitlab.com/ee/ci/) would help teams release software faster and more efficiently; however, it’s nice to see confirmation and put some numbers to the difference it can make. The survey shows that respondents [practicing CI/CD](https://about.gitlab.com/blog/how-to-keep-up-with-ci-cd-best-practices/) were twice as likely to deploy multiple times per day and 1.2 times more likely to release software faster than they did a year ago.\n\nDespite the value of CI/CD for driving efficiency, respondents also identified challenges. For instance, an IT operations associate in the aerospace/defense sector pointed to “management that doesn't understand CI/CD at all” as a blocker to more efficient software development. Meanwhile, a software development intern in the biotech sector shared that “tools to automate CI/CD, together with code editors, APM software, and defect trackers, can help with a faster and quality development cycle,” but “companies are hesitant to spend on tools that can help increase their developers’ productivity.” These responses underscore the value of investing in tools that unify CI/CD with other DevSecOps practices — such as incorporating security early in the development process and creating tighter feedback loops — to help organizations break down development silos.\n\n## 4. DORA and other metrics\nOrganizations that [make a conscious effort to track key development metrics](https://about.gitlab.com/blog/how-zoopla-uses-dora-metrics-and-your-team-can-too/) are more likely to improve them, according to the survey. This makes sense because by virtue of an organization choosing to track a metric, they’re signaling to their teams that it’s important, likely reminding them of whether the metric is improving (or not) periodically, and quite possibly prioritizing initiatives aimed at improving those metrics. We found that respondents whose organizations track their [DORA metrics](https://docs.gitlab.com/ee/user/analytics/dora_metrics.html) and other similar metrics were 1.4 times more likely to deploy multiple times per day.\n\n## A deeper dive on productivity and efficiency\n\nFor a deeper look into release velocity and deployment frequency, and all the practices that made respondents more likely to release software faster and deploy multiple times per day, check out our [2023 DevSecOps Report: Productivity & Efficiency Within Reach](https://about.gitlab.com/developer-survey/).\n\nThe report also digs into two other key factors that can have a big impact on productivity and efficiency: how long it takes to onboard new developers and how difficult or easy it is for organizations to attract, hire, and retain developers. We’ll show you where things stand and the practices that made respondents more likely to be successful.\n\n_[Read the highlights from “Security Without Sacrifices,” the first report in our 2023 Global DevSecOps Report series.](/blog/gitlab-survey-highlights-wins-challenges-as-orgs-adopt-devsecops/)_\n","insights",[952,109,953,9],"developer survey","cloud native",{"slug":955,"featured":6,"template":698},"best-practices-leading-orgs-to-release-software-faster","content:en-us:blog:best-practices-leading-orgs-to-release-software-faster.yml","Best Practices Leading Orgs To Release Software Faster","en-us/blog/best-practices-leading-orgs-to-release-software-faster.yml","en-us/blog/best-practices-leading-orgs-to-release-software-faster",{"_path":961,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":962,"content":968,"config":975,"_id":977,"_type":14,"title":978,"_source":16,"_file":979,"_stem":980,"_extension":19},"/en-us/blog/betstudios-cto-on-improving-ci-cd-capabilities-with-gitlab-premium",{"title":963,"description":964,"ogTitle":963,"ogDescription":964,"noIndex":6,"ogImage":965,"ogUrl":966,"ogSiteName":686,"ogType":687,"canonicalUrls":966,"schema":967},"Betstudios CTO on improving CI/CD capabilities with GitLab Premium","Read why Betstudios upgraded to GitLab Premium and how their software development process has changed in this Q&A with their CTO Rafael Campuzano.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663000/Blog/Hero%20Images/tanukilifecycle.png","https://about.gitlab.com/blog/betstudios-cto-on-improving-ci-cd-capabilities-with-gitlab-premium","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Betstudios CTO on improving CI/CD capabilities with GitLab Premium\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kristina Weis\"}],\n        \"datePublished\": \"2023-12-06\",\n      }",{"title":963,"description":964,"authors":969,"heroImage":965,"date":970,"body":971,"category":972,"tags":973},[947],"2023-12-06","Since joining [Betstudios](https://betstudios.com/en/) (soon to be part of WA. Technology Group) as their CTO earlier this year, Rafael Campuzano has been focused on finding ways to help the software development team save time, automate manual processes, and have a better experience.\n\nThe team had been using GitLab’s free tier for source code management and version control for several years, but they wanted to improve their CI/CD capabilities so they made the decision to upgrade to GitLab Premium. We talked with Rafael about what the team has already been able to do, how their software development process has changed, and what they’re planning to do next.\n\n__What led you to upgrade from GitLab’s free tier to GitLab Premium?__\n\nThe main motivation when I joined Betstudios was to have the service hosted outside our office servers and remove the hassle of having to manage it ourselves, so we decided to move to the SaaS model. Once that decision was made, we needed a certain level of reliability but mainly we wanted to improve our [CI/CD capabilities](https://about.gitlab.com/topics/ci-cd/), which was the reason for upgrading to the Premium plan.\n\n__What made you choose GitLab?__\n\nBetstudios was already using GitLab and I had experience from previous companies and knew that GitLab is a quite complete tool for managing code and beyond. Besides, I also liked the openness and the overall culture of the company, based on transparency and innovation.\n\n__How has your software development process changed since adopting GitLab Premium?__\n\nWe’re a small team and haven’t been able to take full advantage of all the power that GitLab Premium brings yet, but we’ve started with some deployment automations and that’s taken away a lot of unnecessary work — and mistakes — from the teams.\n\n__What benefits have you seen since you started using GitLab Premium?__\n\nWe’re just getting started, but we have already saved around five hours per week per Team Lead by automating much of the deployment process, and soon we expect to take that to 10 hours per week of time saved. Now they can dedicate this time to better planning, code reviews, and even coding.\n\n__You also moved from GitLab's free tier to GitLab Premium at your last company. How did that experience affect your decision to upgrade to GitLab Premium at Betstudios?__\n\nI was responsible for infrastructure at [EveryMatrix](https://about.gitlab.com/customers/everymatrix/), which included the support of the GitLab servers on-prem. We needed HA (high availability), so we decided to move to the Premium plan. However, we soon realized we made many development teams happy, because they wanted to use the more advanced features that the Premium plan was coming with. The development teams showed it was a great decision for them, and our relationship with GitLab the company was always great, so when I arrived at Betstudios it was a clear move to make.\n\n__What would you like to do next with GitLab’s DevSecOps Platform?__\n\nI would like to explore the CI/CD capabilities with Kubernetes, and I’m encouraging our Engineering teams to use all the capabilities like code reviews, advanced merge requests, and CI/CD more and more. I’ve also seen that many companies are using ArgoCD in combination with GitLab and I’m going to explore if there is a way to do everything just using GitLab.\n\n__Do you have any advice for teams getting started with GitLab?__\n\nIt is an all-in-one platform, so you do not need to build complex systems for different tasks around your code production, methodologies, and operations. GitLab is easy to use and has a great team that will help you to get the most out of it.\n\n> Read more GitLab customer stories on our [customers page](https://about.gitlab.com/customers/).","customer-stories",[9,496,109,974],"customers",{"slug":976,"featured":6,"template":698},"betstudios-cto-on-improving-ci-cd-capabilities-with-gitlab-premium","content:en-us:blog:betstudios-cto-on-improving-ci-cd-capabilities-with-gitlab-premium.yml","Betstudios Cto On Improving Ci Cd Capabilities With Gitlab Premium","en-us/blog/betstudios-cto-on-improving-ci-cd-capabilities-with-gitlab-premium.yml","en-us/blog/betstudios-cto-on-improving-ci-cd-capabilities-with-gitlab-premium",{"_path":982,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":983,"content":989,"config":996,"_id":998,"_type":14,"title":999,"_source":16,"_file":1000,"_stem":1001,"_extension":19},"/en-us/blog/building-a-more-inclusive-and-welcoming-open-source-community-on-gitlab",{"title":984,"description":985,"ogTitle":984,"ogDescription":985,"noIndex":6,"ogImage":986,"ogUrl":987,"ogSiteName":686,"ogType":687,"canonicalUrls":987,"schema":988},"Building a more inclusive and welcoming open source community on GitLab","Open source projects using GitLab can now easily apply for CHAOSS DEI badges.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683305/Blog/Hero%20Images/AdobeStock_449040869.jpg","https://about.gitlab.com/blog/building-a-more-inclusive-and-welcoming-open-source-community-on-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Building a more inclusive and welcoming open source community on GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Emilio Salvador\"}],\n        \"datePublished\": \"2024-01-29\",\n      }",{"title":984,"description":985,"authors":990,"heroImage":986,"date":992,"body":993,"category":994,"tags":995},[991],"Emilio Salvador","2024-01-29","At GitLab, our mission is to create a world where everyone can contribute. To keep building that world, we want to equip open source projects using GitLab with tools to foster more inclusive and welcoming communities.\nToday we're announcing one of those tools.\n\nWe're excited to share that GitLab has partnered with the Community Health Analytics in Open Source Software ([CHAOSS](https://chaoss.community/)) project to integrate GitLab with their [recently released DEI Project Badging program](https://go.gitlab.com/JKwGOR). The DEI Project Badging program enables open source projects to:\n- Clearly signal their focus on building diverse communities\n- More easily highlight the work they are doing to welcome and support new members\n- Add visual badges to their projects to indicate their community's reflection on the CHAOSS DEI badging metrics\n\nGitLab is already [badged](https://go.gitlab.com/QFJutN). Many of our open source partners are joining us (see below). Now your project can be badged, too. Everything you need to start using this new integration is on the [CHAOSS Project Badging](https://go.gitlab.com/qEcu1s) site.\n\nRead on to learn how this initiative came together — and how you can get involved.\n\n## Productive CHAOSS\nFinding an open source community to learn, connect, and grow with isn't always easy. In fact, [a Linux Foundation report on diversity, equity, and inclusion](https://www.linuxfoundation.org/research/the-2021-linux-foundation-report-on-diversity-equity-and-inclusion-in-open-source) (DEI) in open source communities highlighted just how difficult it can be for certain contributors.\nOpen source contributors from underrepresented groups were more likely to feel unwelcome and experience exclusionary practices. The report noted barriers to representation in leadership and language blockers around reading and writing in the English language. Here are some findings from the report:\n- 36% of respondents reported experiencing some form of stereotyping behavior based on perceived demographic characteristics. \n- 30% of respondents were unsure a code of conduct would be enforced. \n- 22% of respondents disagreed that equal opportunity exists for people with different backgrounds to be part of the decision-making process.\n\nThese numbers are concerning. But to anyone familiar with the struggles of diversity, equity, and inclusion in open source, they're likely not surprising, either.\n\nTo better align on best practices for building inclusive open source communities, and to ensure that [GitLab's company DEI value](https://handbook.gitlab.com/handbook/company/culture/inclusion/) is reflected in our contributor community, GitLab partnered with an authoritative source: the [CHAOSS DEI working group](https://chaoss.community/diversity-and-inclusion-badging/). Founded in 2017, the [CHAOSS community](https://chaoss.community/) is a Linux Foundation project that defines open source community health metrics.\n\nThe group builds tools that everyone working in open source — maintainers, developers, and community managers alike — can use to spot trends in their open source projects. Ultimately, CHAOSS wants to enable everyone to create healthier and more sustainable open source communities.\n\nThe CHAOSS DEI working group asked us to reflect on their open source [inclusivity metrics](https://github.com/badging/ProjectBadging/blob/main/Template.DEI.md) and showcase what we were doing at GitLab to build a more inclusive open source ecosystem. They also invited us to contribute to one of their most ambitious projects: a system of badges that open source communities can use to clearly signal their dedication to making that ecosystem a more supportive place.\n\n### How the DEI Project Badging system works\nIt works like this.\n\nOpen source projects compose DEI Project Statements and place those statements prominently in their codebases (as a file named DEI.md). Writing the statement involves taking a real, hard look at what DEI means for a project's unique community — not just signing off on a shared, generalized statement. By publicly sharing these statements, the entire open source ecosystem learns and grows collectively.\n\nCHAOSS offers an automated tool for scanning a project repository for the presence of the DEI.md file, then returns its contents to CHAOSS for review. If the project meets the CHAOSS project's criteria for diversity, equity, and inclusion, CHAOSS awards that project a badge, signifying its status as an inclusive project.\n\n\"CHAOSS spends a lot of time thinking about open source community health, so we are thrilled to be able to help open source projects better communicate and surface their efforts to build more inclusive communities,\" says Elizabeth Barron, a community manager for CHAOSS. \"We are hopeful that advocating for a more consistent way to do so (via a DEI.md file) will offer a better way for a project to share their approach with other projects, in true open source fashion.\"\n\nWe liked what we saw. And we knew we could pitch in — not just by writing and certifying our own [DEI Project Statement](https://go.gitlab.com/QFJutN), but by integrating the CHAOSS project's tool with GitLab so other communities could, too.\n\n## GitLab contributes\nSo we got to work. We examined practices from teams across GitLab, including Developer Relations, Contributor Success, GitLab UX, the Product Accessibility working group, and the Diversity, Inclusion and Belonging team. To help draft an initial Bronze tier for the DEI Badging program, we shared example practices from GitLab, including:\n- GitLab's project maintainers and merge request coaches span global timezones and work asynchronously with contributors across the world.\n- GitLab operates the GitLab Unfiltered YouTube channel that shares all publicly available meetings, recordings, and community pairing sessions.\n- GitLab uses weekly triage reports on first-time contributors who are awaiting a response to a merge request. This ensures newcomers always hear back from a real person about their merge request.\n\nIn partnership with CHAOSS, we'll continue to build more tiers into the program. This will help motivate projects to continue their DEI efforts and reflect on more CHAOSS DEI metrics.\n\nAnd we've made it easier for open source projects on GitLab to get badged, too, by collaborating with CHAOSS to directly integrate GitLab with the badging application process. The CHAOSS badging website features a \"Login with GitLab\" button, which provides project owners a single-click connection between their GitLab projects and CHAOSS. \n\nFor communities using GitLab to build open source software, this makes submitting a project and scanning it for a DEI.md file fast and easy. For self-hosted GitLab projects, applicants can submit a form on the CHAOSS badging website to get a review.\n\nTo help sustain this initiative, GitLab is sponsoring the CHAOSS Africa chapter, the team behind development of the DEI Project Badging system. Since its inception in 2022, CHAOSS Africa has seen impressive growth while solving the challenges of open source communities in Africa and helping newcomers become open source contributors.\u2028 We're eager to see what they continue building together with their communities.\n\n## With help from our friends\nWe're not acting alone. Building a more diverse, equitable, and inclusive open source ecosystem requires collective commitment. In that spirit, several of our [open source partners](https://about.gitlab.com/solutions/open-source/partners/) are announcing their support of the badging integration.\n\nHere's what they had to say:\n\n\"The [Drupal Association](https://www.drupal.org/) is proud to be reinforcing our longstanding commitment to diversity, equity, inclusion, and justice by partnering with CHAOSS and GitLab right at the launch of this initiative. Drupal is recognized as a Digital Public Good by the United Nations-endorsed Digital Public Goods Alliance, and we feel the responsibility of building a better, more open internet that recognizes, elevates, and serves historically underrepresented communities. We're hopeful that this effort is part of a sea change in open source communities, and software development in general, to better recognize, evaluate, and redress DEI challenges that we have a collective responsibility to solve. We believe this metric-driven approach will help projects reinforce each other's good behavior, and inspire the industry as a whole. We're looking forward to cataloging our DEI commitments according to this new process, to share and compare with the wider ecosystem.\" **— [Tim Lehnen](https://gitlab.com/hestenet-drupal), CTO, Drupal Association**\n\n\"[The Good Docs Project](https://thegooddocsproject.dev/) is excited to join with CHAOSS and GitLab to promote the values of diversity, equity, and inclusion in open source. We want to empower our community members to do their best work and be their authentic selves. By participating in this initiative, we hope to think deeply about how we can promote greater diversity, equity, and inclusion in our project and then develop concrete policies and actions to support those goals. We pledge to develop our policies and earn our DEI badge from CHAOSS within the next few months.\" **— [Alyssa Rock](https://gitlab.com/barbaricyawps), Community Manager, The Good Docs Project**\n\n\"The integration of CHAOSS project's diversity, equity, and inclusion (DEI) initiative with GitLab is an important milestone for building more inclusive open source software, one that resonates on all levels with our [Colmena Project](https://blog.colmena.media/). The initiative creates the necessary visibility for many inclusive open source projects, not only paves the way for an ecosystem-focused approach to software development in general, but also encourages greater cooperation at a peer-to-peer level. It enables community members to recognize the vast diversity of contexts involved in the work of software development, and to inspire each other. This is important to the Colmena project, which is focused on supporting community and local media that makes visible the reality of indigenous peoples, women, youth, and different identities that are not part of the agenda of mainstream media. Participating in this initiative gives us the opportunity to better recognize DEI challenges and constantly reflect on our work to readjust and improve our efforts. We commit to continuing the dialogue with our community on these issues, documenting our efforts transparently and making necessary readjustments to policies and procedures.\" **— [Nils Brock](https://gitlab.com/nilsbrock), Program Director, Colmena**\n\n\"The [Kali Linux](https://www.kali.org/) team is very proud to have been invited to take part in this initiative, and we are looking forward to what it means for the open source community. We are committed to being as inclusive as possible and hope to demonstrate that through our efforts. For more information on what we are planning on doing to support it, please read our [DEI Promise](https://www.kali.org/blog/dei-promise/).\" **— [Joe O'Gorman](https://gitlab.com/Gamb1t), Community Manager, Kali Linux**\n\n## Let's build together\nThe work is far from over.\n\n\"We are committed to diversifying open source communities on GitLab. It's a critical part of our strategy for Diversity, Equity, and Inclusion, at GitLab in 2024 and beyond,\" says Sherida McMullan, Vice President of Diversity Inclusion & Belonging at GitLab. \"This DEI Project Badging program launched in partnership with CHAOSS helps us to make great strides in fostering an inclusive open source space and highlighting inclusive projects. As we enter Black History month, this is just the beginning of the impact we are looking to make in GitLab's open source communities.\"\n\nWe invite every member of the GitLab community to join us in making the open source community on GitLab a more diverse, more equitable, and more inclusive place to build the future together. Get started today by certifying your project, contributing to GitLab, and helping us create a world where everyone can contribute.","news",[994,496,9],{"slug":997,"featured":6,"template":698},"building-a-more-inclusive-and-welcoming-open-source-community-on-gitlab","content:en-us:blog:building-a-more-inclusive-and-welcoming-open-source-community-on-gitlab.yml","Building A More Inclusive And Welcoming Open Source Community On Gitlab","en-us/blog/building-a-more-inclusive-and-welcoming-open-source-community-on-gitlab.yml","en-us/blog/building-a-more-inclusive-and-welcoming-open-source-community-on-gitlab",{"_path":1003,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1004,"content":1010,"config":1017,"_id":1019,"_type":14,"title":1020,"_source":16,"_file":1021,"_stem":1022,"_extension":19},"/en-us/blog/building-a-text-adventure-using-cplusplus-and-code-suggestions",{"title":1005,"description":1006,"ogTitle":1005,"ogDescription":1006,"noIndex":6,"ogImage":1007,"ogUrl":1008,"ogSiteName":686,"ogType":687,"canonicalUrls":1008,"schema":1009},"Explore the Dragon Realm: Building a C++ adventure game with AI","How to use GitLab Duo Code Suggestions to create a text-based adventure game, including magical locations to visit and items to procure, using C++.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663344/Blog/Hero%20Images/compassinfield.jpg","https://about.gitlab.com/blog/building-a-text-adventure-using-cplusplus-and-code-suggestions","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Explore the Dragon Realm: Build a C++ adventure game with a little help from AI\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Fatima Sarah Khalid\"}],\n        \"datePublished\": \"2023-08-24\",\n      }",{"title":1011,"description":1006,"authors":1012,"heroImage":1007,"date":1013,"body":1014,"category":781,"tags":1015},"Explore the Dragon Realm: Build a C++ adventure game with a little help from AI",[713],"2023-08-24","Learning, for me, has never been about reading a textbook or sitting in on a\nlecture - it's been about experiencing and immersing myself in a hands-on\nchallenge. This is particulary true for new programming languages. With\n[GitLab Duo Code Suggestions](https://about.gitlab.com/gitlab-duo/),\nartificial intelligence (AI) becomes my interactive guide, providing an\nenvironment for trial, error, and growth. In this tutorial, we will build a\ntext-based adventure game in C++ by using Code Suggestions to learn the\nprogramming language along the way.\n\n\nYou can use this table of contents to navigate into each section. It is\nrecommended to read top-down for the best learning experience.\n\n\n- [Setup](#setup)\n  - [Installing VS Code](#installing-vs-code)\n  - [Installing Clang as a compiler](#installing-clang-as-a-compiler)\n  - [Setting up VS Code](#setting-up-vs-code)\n- [Getting started](#getting-started)\n  - [Compiling and running your program](#compiling-and-running-your-program)\n- [Setting the text adventure stage](#setting-the-adventure-stage)\n\n- [Defining the adventure: Variables](#defining-the-adventure-variables)\n\n- [Crafting the adventure: Making decisions with\nconditionals](#crafting-the-adventure-making-decisions-with-conditionals)\n\n- [Structuring the narrative:\nCharacters](#structuring-the-narrative-characters)\n\n- [Structuring the narrative: Items](#structuring-the-narrative-items)\n\n- [Applying what we've learned at the Grand\nLibrary](#applying-what-weve-learned-at-the-grand-library)\n\n- [See you next time in the Dragon\nRealm](#see-you-next-time-in-the-dragon-realm)\n\n- [Share your feedback](#share-your-feedback)\n\n\n> Download [GitLab Ultimate for free](https://about.gitlab.com/gitlab-duo/)\nfor a trial of GitLab Duo Code Suggestions.\n\n\n## Setup\n\nYou can follow this tutorial in your [preferred and supported\nIDE](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-in-other-ides-and-editors).\nReview the documentation to enable Code Suggestions for [GitLab.com\nSaaS](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-on-gitlab-saas)\nor [GitLab self-managed\ninstances](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-on-self-managed-gitlab).\n\n\nThese installation instructions are for macOS Ventura on M1 Silicon. \n\n\n### Installing VS Code\n\n\n* Download and install [VS Code](https://code.visualstudio.com/download).\n\n* Alternatively, you can also install it as a Homebrew cask: `brew install\n--cask visual-studio-code`.\n\n\n### Installing Clang as a compiler\n\n\n* On macOS, you'll need to install some developer tools. Open your terminal\nand type:\n\n\n```\n\nxcode-select --install\n\n```\n\n\nThis will prompt you to install Xcode's command line tools, which include\nthe [Clang C++ compiler](https://clang.llvm.org/get_started.html).\n\n\nAfter the installation, you can check if `clang++` is installed by typing:\n\n\n```\n\nclang++ --version\n\n```\n\n\nYou should see an output that includes some information about the Clang\nversion you have installed. \n\n\n### Setting up VS Code\n\n\n* Launch VS Code.\n\n* Install and configure [the GitLab Workflow\nextension](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow).\n\n* Optionally, in VS Code, install the [C/C++ Intellisense\nextension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools),\nwhich helps with debugging C/C++. \n\n\n## Getting started\n\nNow, let's start building this magical adventure with C++. We'll start with\na \"Hello World\" example.\n\n\nCreate a new project `learn-ai-cpp-adventure`. In the project root, create\n`adventure.cpp`. The first part of every C++ program is the `main()`\nfunction. It's the entry point of the program.\n\n\nWhen you start writing `int main() {`, Code Suggestions will help\nautocomplete the function with some default parameters.\n\n\n![adventure.cpp with a hello world implementation suggested by Code\nSuggestions](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/0-helloworld.png){:\n.shadow}\n\n\n```cpp\n\nint main()\n\n{\n    cout \u003C\u003C \"Hello World\" \u003C\u003C endl;\n    return 0;\n}\n\n```\n\n\nWhile this is a good place to start, we need to add an include and update\nthe output statement:\n\n\n```cpp\n\n#include \u003Ciostream> // Include the I/O stream library for input and output\n\n\n// Main function, the starting point of the program\n\nint main()\n\n{\n    // Print \"Hello World!\" to the console\n    std::cout \u003C\u003C \"Hello World!\" \u003C\u003C std::endl;\n\n    // Return 0 to indicate successful execution\n    return 0;\n}\n\n```\n\n\nThe program prints \"Hello World!\" to the console when executed.\n\n\n* `#include \u003Ciostream>`: Because we are building a text-based adventure, we\nwill rely on input from the player using input and output operations (I/O)\nin C++. This include is a preprocessor directive that tells our program to\ninclude the `iostream` library, which provides facilities to use input and\noutput streams, such as `std::cout` for output.\n\n\n* You might find that Code Suggestions suggests `int main(int argc, char*\nargv[])` as the definition of our main function. The parameters `(int argc,\nchar* argv[])` are used to pass command-line arguments to the program. Code\nSuggestions added them as default parameters, but they are not needed if\nyou're not using command-line arguments. In that case, we can also define\nthe main function as `int main()`.\n\n\n* `std::cout \u003C\u003C \"Hello World!\" \u003C\u003C std::endl;`: outputs \"Hello World\" to the\nconsole. The stream operator `\u003C\u003C` is used to send the string to output.\n`std::endl` is an end-line character.\n\n\n* `return 0;`: we use `return 0;` to indicate the end of the `main()`\nfunction and return a value of 0. In C++, it is good practice to return 0 to\nindicate the program has completed successfully.\n\n\n### Compiling and running your program\n\nNow that we have some code, let's review how we'll compile and run this\nprogram. \n\n* Open your terminal or use the terminal in VSCode (View -> Terminal).\n\n* Navigate to your project directory.\n\n* Compile your program by typing:\n\n\n```bash\n\nclang++ adventure.cpp -o adventure\n\n```\n\n\nThis command tells the Clang++ compiler to compile adventure.cpp and create\nan executable named adventure. After this, run your program by typing:\n\n\n```\n\n./adventure\n\n```\n\n\nYou should see \"Hello World!\" printed in the terminal. \n\n\nBecause our tutorial uses a single source file `adventure.cpp`, we can use\nthe compiler directly to build our program. In the future, if the program\ngrows beyond a file, we'll set up additional configurations to handle\ncompilation. \n\n\n## Setting the text adventure stage\n\nBefore we get into more code, let's set the stage for our text adventure.\n\n\nFor this text adventure, players will explore the Dragon Realm. The Dragon\nRealm is full of mountains, lakes, and magic. Our player will enter the\nDragon Realm for the first time, explore different locations, meet new\ncharacters, collect magical items, and journal their adventure. At every\nlocation, they will be offered choices to decide the course of their\njourney.\n\n\nTo kick off our adventure into the Dragon Realm, let's update our\n`adventure.cpp main()` function to be more specific. As you update the\nwelcome message, you might find that Code Suggestions already knows we're\nbuilding a game.\n\n\n![adventure.cpp - Code Suggestions offers suggestion of welcoming users to\nthe Dragon Realm and knows its a\ngame](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/1-welcome-to-the-realm.png){:\n.shadow}\n\n\n```cpp\n\n#include \u003Ciostream> // Include the I/O stream library for input and output\n\n\n// Main function, the starting point of the program\n\nint main()\n\n{\n    // Print \"Hello World!\" to the console\n    std::cout \u003C\u003C \"Welcome to the Dragon Realm!\" \u003C\u003C std::endl;\n\n    // Return 0 to indicate successful execution\n    return 0;\n}\n\n```\n\n\n## Defining the adventure: Variables\n\nA variable stores data that can be used throughout the program scope in the\n`main()` function. A variable is defined by a type, which indicates the kind\nof data it can hold.\n\n\nLet's create a variable to hold our player's name and give it the type\n`string`. A `string` is designed to hold a sequence of characters so it's\nperfect for storing our player's name.\n\n\n```cpp\n\n#include \u003Ciostream> // Include the I/O stream library for input and output\n\n\n// Main function, the starting point of the program\n\nint main()\n\n{\n    // Print \"Hello World!\" to the console\n    std::cout \u003C\u003C \"Welcome to the Dragon Realm!\" \u003C\u003C std::endl;\n\n    // Declare a string variable to hold the player's name\n    std::string playerName;\n\n    // Return 0 to indicate successful execution\n    return 0;\n}\n\n```\n\n\nAs you do this, you may notice that Code Suggestions knows what's coming\nnext - prompting the user for their player's name.\n\n\n![adventure.cpp - Code Suggestions suggests welcoming the player with the\nplayerName\nvariable](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/2-player-name-variable.png){:\n.shadow}\n\n\nWe may be able to get more complete and specific Code Suggestions by\nproviding comments about what we'd like to do with the name - personally\nwelcome the player to the game. Start by adding our plan of action in\ncomments.\n\n\n```cpp\n    // Declare a string variable to hold the player's name\n    std::string playerName;\n\n    // Prompt the user to enter their player name\n\n    // Display a personalized welcome message to the player with their name\n```\n\n\nTo capture the player's name from input, we need to use the `std::cin`\nobject from the `iostream` library to fetch input from the player using the\nextraction operator `>>`. If you start typing `std::` to start prompting the\nuser, Code Suggestions will make some suggestions to help you gather user\ninput and save it to our `playerName` variable.\n\n\n![adventure.cpp - Code Suggestions prompts the user to input their player\nname](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/2.1-player-name-input.png){:\n.shadow}\n\n\nNext, to welcome our player personally to the game, we want to use\n`std::cout` and the `playerName` variable together:\n\n\n```cpp\n    // Declare a string variable to store the player name\n    std::string playerName;\n\n    // Prompt the user to enter their player name\n    std::cout \u003C\u003C \"Please enter your name: \";\n    std::cin >> playerName;\n\n    // Display a personalized welcome message to the player with their name\n    std::cout \u003C\u003C \"Welcome \" \u003C\u003C playerName \u003C\u003C \" to The Dragon Realm!\" \u003C\u003C std::endl;\n```\n\n\n## Crafting the adventure: Making decisions with conditionals\n\nIt's time to introduce our player to the different locations in tbe Dragon\nRealm they can visit. To prompt our player with choices, we use\nconditionals. Conditionals allow programs to take different actions based on\ncriteria, such as user input.\n\n\nLet's offer the player a selection of locations to visit and capture their\nchoice as an `int` value that corresponds to the location they picked.\n\n\n```cpp\n\n// Display a personalized welcome message to the player with their name\n\nstd::cout \u003C\u003C \"Welcome \" \u003C\u003C playerName \u003C\u003C \" to The Dragon Realm!\" \u003C\u003C\nstd::endl;\n\n\n// Declare an int variable to capture the user's choice\n\nint choice;\n\n```\n\n\nThen, we want to offer the player the different locations that are possible\nfor that choice. Let's start with a comment and prompt Code Suggestions with\n`std::cout` to fill out the details for us.\n\n\n![adventure.cpp - Code Suggestions suggests a multiline output for all the\nlocations listed in the code\nbelow](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3-setup-location-choice.png){:\n.shadow}\n\n\nAs you accept the suggestions, Code Suggestions will help build out the\noutput and ask the player for their input.\n\n\n![adventure.cpp - Code Suggestions suggests a multiline output for all the\nlocations listed in the code below and asks for player\ninput](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.1-capture-player-location-choice.png){:\n.shadow}\n\n\n```cpp\n    // Declare an int variable to capture the user's choice\n    int choice;\n\n    // Offer the player a choice of 3 locations: 1 for Moonlight Markets, 2 for Grand Library, and 3 for Shimmer Lake.\n    std::cout \u003C\u003C \"Where will \" \u003C\u003C playerName \u003C\u003C \" go?\" \u003C\u003C std::endl;\n    std::cout \u003C\u003C \"1. Moonlight Markets\" \u003C\u003C std::endl;\n    std::cout \u003C\u003C \"2. Grand Library\" \u003C\u003C std::endl;\n    std::cout \u003C\u003C \"3. Shimmer Lake\" \u003C\u003C std::endl;\n    std::cout \u003C\u003C \"Please enter your choice: \";\n    std::cin >> choice;\n```\n\n\nOnce you start typing `std::cin >>` or accept the prompt for asking the\nplayer for their choice, Code Suggestions might offer a suggestion for\nbuilding out your conditional flow. AI is non-deterministic: One suggestion\ncan involve if/else statements while another solution uses a switch\nstatement.\n\n\nTo give Code Suggestions a nudge, we'll add a comment and start typing out\nan if statement: `if (choice ==)`.\n\n\n![adventure.cpp - Code Suggestions suggests using an if statement to manage\nchoice of\nlocations](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.2-if-statement-locations.png){:\n.shadow}\n\n\nAnd if you keep accepting the subsequent suggestions, Code Suggestions will\nautocomplete the code using if/else statements.\n\n\n![adventure.cpp - Code Suggestions helps the user fill out the rest of the\nif/else statements for choosing a\nlocation](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.2.1-if-statement-locations-continued.png){:\n.shadow}\n\n\n```cpp\n    // Check the user's choice and display the corresponding messages\n    if (choice == 1) {\n        std::cout \u003C\u003C \"You chose Moonlight Markets\" \u003C\u003C std::endl;\n    }\n    else if (choice == 2) {\n        std::cout \u003C\u003C \"You chose Grand Library\" \u003C\u003C std::endl;\n    }\n    else if (choice == 3) {\n        std::cout \u003C\u003C \"You chose Shimmer Lake\" \u003C\u003C std::endl;\n    }\n    else {\n        std::cout \u003C\u003C \"Invalid choice\" \u003C\u003C std::endl;\n    }\n```\n\n\n`if/else` is a conditional statement that allows a program to execute code\nbased on whether a condition, in this case the player's choice, is true or\nfalse. If the condition evaluates to true, the code inside the braces is\nexecuted.\n\n\n* `if (condition)`: used to check if the condition is true.\n\n* `else if (another condition)`: if the previous condition isn't true, the\nprograms checks this condition.\n\n* `else`: if none of the previous conditions are true.\n\n\nAnother way of managing multiple choices like this example is using a\n`switch()` statement. A `switch` statement allows our program to jump to\ndifferent sections of code based on the value of an expression, which, in\nthis case, is the value of `choice`.\n\n\nWe are going to replace our `if/else` statements with a `switch` statement.\nYou can comment out or delete the `if/else` statements and prompt Code\nSuggestions starting with `switch(choice) {`.\n\n\n![adventure.cpp - Code Suggestions helps the user handle the switch\nstatement for the\nlocations](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.3-conditional-switch-locations.png){:\n.shadow}\n\n\n![adventure.cpp - Code Suggestions helps the user handle the switch\nstatement for the\nlocations](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.3.1-conditional-switch-locations-continued.png){:\n.shadow}\n\n\n```cpp\n    // Evaluate the player's decision\n    switch(choice) {\n        // If 'choice' is 1, this block is executed.\n        case 1:\n            std::cout \u003C\u003C \"You chose Moonlight Markets.\" \u003C\u003C std::endl;\n            break;\n        // If 'choice' is 2, this block is executed.\n        case 2:\n            std::cout \u003C\u003C \"You chose Grand Library.\" \u003C\u003C std::endl;\n            break;\n        // If 'choice' is 3, this block is executed.\n        case 3:\n            std::cout \u003C\u003C \"You chose Shimmer Lake.\" \u003C\u003C std::endl;\n            break;\n        // If 'choice' is not 1, 2, or 3, this block is executed.\n        default:\n            std::cout \u003C\u003C \"You did not enter 1, 2, or 3.\" \u003C\u003C std::endl;\n    }\n```\n\n\nEach case represents a potential value that the variable or expression being\nswitched on (in this case, choice) could have. If a match is found, the code\nfor that case is executed. We use the `default` case to handle any input\nerrors in case the player enters a value that isn't accounted for.\n\n\nLet's build out what happens when our player visits the Shimmering Lake.\nI've added some comments after the player's arrival at Shimmering Lake to\nprompt Code Suggestions to help us build this out:\n\n\n```cpp\n    // If 'choice' is 3, this block is executed.\n    case 3:\n        std::cout \u003C\u003C \"You chose Shimmering Lake.\" \u003C\u003C std::endl;\n        // The player arrives at Shimmering Lake. It is one of the most beautiful lakes the player has ever seen.\n        // The player hears a mysterious melody from the water.\n        // They can either 1. Stay quiet and listen, or 2. Sing along with the melody.\n\n        break;\n```\n\n\nNow, if you start writing `std::cout` to begin offering the player this new\ndecision point, Code Suggestions will help fill out the output code.\n\n\n![adventure.cpp - Code Suggestions helps fill out the output code based on\nthe comments about the interaction at the\nLake](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.4-case-3-output.png){:\n.shadow}\n\n\nYou might find that the code provided by Code Suggestions is very\ndeclarative. Once I've accepted the suggestion, I personalize the code as\nneeded. For example in this case, including the melody the player heard and\nusing the player's name instead of \"you\":\n\n\n![adventure.cpp - I added the playerName to the output and then prompted\nCode Suggestions to continue the narrative based on the comments\nabove](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.4.1-customizing-output.png){:\n.shadow}\n\n\nI also wanted Code Suggestions to offer suggestions in a specific format, so\nI added an end line:\n\n\n![adventure.cpp - I added an end line to prompt Code Suggestions to break\nthe choices into end line\noutputs](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.4.2-customizing-output-endline.png){:\n.shadow}\n\n\n![adventure.cpp - I added an endline to prompt Code Suggestions to break the\nchoices into end line\noutputs](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.4.3-sub-choices-output.png){:\n.shadow}\n\n\nNow, we'd like to offer our player a nested choice in this scenario. Before\nwe can define the new choices, we need a variable to store this nested\nchoice. Let's define a new variable `int nestedChoice` in our `main()`\nfunction, outside of the `switch()` statement we set up. You can put it\nafter our definition of the `choice` variable.\n\n\n```cpp\n    // Declare an int variable to capture the user's choice\n    int choice;\n    // Declare an int variable to capture the user's nested choice\n    int nestedChoice;\n```\n\n\nNext, returning to the `if/else` statement we were working on in `case 3`,\nwe want to prompt the player for their decision and save it in\n`nestedChoice`.\n\n\n![adventure.cpp - I added an end line to prompt Code Suggestions to break\nthe choices into end line\noutputs](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.4.4-capture-nested-choice.png){:\n.shadow}\n\n\nAs you can see, Code Suggestions wants to go ahead and handle the user's\nchoice using another `switch` statement. I would prefer to use an `if/else`\nstatement to handle this decision point.\n\n\nFirst, let's add some comments to give context:\n\n\n```cpp\n    // Capture the user's nested choice\n    std::cin >> nestedChoice;\n\n    // If the player chooses 1 and remains silent, they hear whispers of the merfolk below, but nothing happens.\n    // If the player chooses 2 and sings along, a merfolk surfaces and gifts them a special blue gem as a token of appreciation for their voice.\n\n    // Evaluate the user's nestedChoice\n```\n\n\nThen, start typing `if (nestedChoice == 1)` and Code Suggestions will start\nto offer suggestions:\n\n\n![adventure.cpp - Code Suggestions starts to build out an if statement to\nhandle the\nnestedChoice](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.5-nested-choice-if.png){:\n.shadow}\n\n\nIf you tab to accept them, Code Suggestions will continue to fill out the\nrest of the nested `if/else` statements.\n\n\nSometimes, while you're customizing the suggestions that Code Suggestions\ngives, you may even discover that it would like to make creative\nsuggestions, too!\n\n\n![adventure.cpp - Code Suggestions makes a creative suggestion to end the\ninteraction with the merfolk by saying \"You are now free to go\" after you\nreceive the\ngem.](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.5.2-nested-cs-creative-suggestion.png){:\n.shadow}\n\n\nHere's the code for `case 3` for the player's interaction at Shimmering Lake\nwith the nested decision. I've updated some of the narrative dialogue\nplayer's name.\n\n```\n    // Handle the Shimmering Lake scenario.\n    case 3:\n        std::cout \u003C\u003C playerName \u003C\u003C \" arrives at Shimmering Lake. It is one of the most beautiful lakes that\" \u003C\u003C playerName \u003C\u003C \" has seen. They hear a mysterious melody from the water. They can either: \" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"1. Stay quiet and listen\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"2. Sing along with the melody\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"Please enter your choice: \";\n\n        // Capture the user's nested choice\n        std::cin >> nestedChoice;\n\n        // If the player chooses to remain silent\n        if (nestedChoice == 1)\n        {\n            std::cout \u003C\u003C \"Remaining silent, \" \u003C\u003C playerName \u003C\u003C \" hears whispers of the merfolk below, but nothing happens.\" \u003C\u003C std::endl;\n        }\n        // If the player chooses to sing along with the melody\n        else if (nestedChoice == 2)\n        {\n            std::cout \u003C\u003C \"Singing along, a merfolk surfaces and gifts \" \u003C\u003C playerName\n                    \u003C\u003C \" a special blue gem as a token of appreciation for their voice.\"\n                    \u003C\u003C std::endl;\n        }\n        break;\n```\n\n\nOur player isn't limited to just exploring Shimmering Lake. There's a whole\nrealm to explore and they might want to go back and explore other locations.\n\n\nTo facilitate this, we can use a `while` loop. A loop is a type of\nconditional that allows a specific section of code to be executed multiple\ntimes based on a condition. For the `condition` that allows our `while` loop\nto run multiple times, let's use a `boolean` to initialize the loop\ncondition.\n\n\n```cpp\n    // Initialize a flag to control the loop and signify the player's intent to explore.\n    bool exploring = true;\n    // As long as the player wishes to keep exploring, this loop will run.\n    while(exploring) {\n        // wrap the code for switch(choice)\n    }\n```\n\n\nWe also need to move our location prompt inside the `while` loop so that the\nplayer can visit more than one location at the time.\n\n\n![adventure.cpp - CS helps us write a go next prompt for the\nlocations](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.6-while-loop-go-next.png){:\n.shadow}\n\n\n```cpp\n    // Initialize a flag to control the loop and signify the player's intent to explore.\n    bool exploring = true;\n    // As long as the player wishes to keep exploring, this loop will run.\n    while(exploring) {\n\n        // If still exploring, ask the player where they want to go next\n        std::cout \u003C\u003C \"Where will \" \u003C\u003C playerName \u003C\u003C \" go next?\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"1. Moonlight Markets\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"2. Grand Library\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"3. Shimmering Lake\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"Please enter your choice: \";\n        // Update value of choice\n        std::cin >> choice;\n\n        // Respond based on the player's main choice\n        switch(choice) {\n```\n\n\nOur `while` loop will keep running as long as `exploring` is `true`, so we\nneed a way for the player to have the option to exit the game. Let's add a\ncase 4 that allows the player to exit by setting `exploring = false`. This\nwill exit the loop and take the player back to the original choices.\n\n\n```cpp\n    // Option to exit the game\n    case 4:\n        exploring = false;\n        break;\n```\n\n\n**Async exercise**: Give the player the option to exit the game instead of\nexploring a new decision.\n\n\nWe also need to update the error handling for invalid inputs in the `switch`\nstatement. You can decide whether to end the program or use the `continue`\nstatement to start a new loop iteration.\n\n\n```cpp\n        default:\n            std::cout \u003C\u003C \"You did not enter a valid choice.\" \u003C\u003C std::endl;\n            continue; // Errors continue with the next loop iteration\n```\n\n\nUsing I/O and conditionals is at the core of text-based adventure games and\nhelps make these games interactive. We can combine user input, display\noutput, and implement our narrative into decision-making logic to create an\nengaging experience.\n\n\nHere's what our `adventure.cpp` looks like now with some comments:\n\n\n```cpp\n\n#include \u003Ciostream> // Include the I/O stream library for input and output\n\n\n// Main function, the starting point of the program\n\nint main()\n\n{\n    std::cout \u003C\u003C \"Welcome to the Dragon Realm!\" \u003C\u003C std::endl;\n\n    // Declare a string variable to store the player name\n    std::string playerName;\n\n    // Prompt the user to enter their player name\n    std::cout \u003C\u003C \"Please enter your name: \";\n    std::cin >> playerName;\n\n    // Display a personalized welcome message to the player with their name\n    std::cout \u003C\u003C \"Welcome \" \u003C\u003C playerName \u003C\u003C \" to The Dragon Realm!\" \u003C\u003C std::endl;\n\n    // Declare an int variable to capture the user's choice\n    int choice;\n    // Declare an int variable to capture the user's nested choice\n    int nestedChoice;\n\n    // Initialize a flag to control the loop and signify the player's intent to explore.\n    bool exploring = true;\n    // As long as the player wishes to keep exploring, this loop will run.\n    while(exploring) {\n\n        // If still exploring, ask the player where they want to go next\n        std::cout \u003C\u003C \"Where will \" \u003C\u003C playerName \u003C\u003C \" go next?\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"1. Moonlight Markets\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"2. Grand Library\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"3. Shimmering Lake\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"Please enter your choice: \";\n        // Update value of choice\n        std::cin >> choice;\n\n        // Respond based on the player's main choice\n        switch(choice) {\n            //  Handle the Moonlight Markets scenario\n            case 1:\n                std::cout \u003C\u003C \"You chose Moonlight Markets.\" \u003C\u003C std::endl;\n                break;\n            // Handle the Grand Library scenario.\n            case 2:\n                std::cout \u003C\u003C \"You chose Grand Library.\" \u003C\u003C std::endl;\n                break;\n            // Handle the Shimmering Lake scenario.\n            case 3:\n                std::cout \u003C\u003C playerName \u003C\u003C \" arrives at Shimmering Lake. It is one of the most beautiful lakes that\" \u003C\u003C playerName \u003C\u003C \" has seen. They hear a mysterious melody from the water. They can either: \" \u003C\u003C std::endl;\n                std::cout \u003C\u003C \"1. Stay quiet and listen\" \u003C\u003C std::endl;\n                std::cout \u003C\u003C \"2. Sing along with the melody\" \u003C\u003C std::endl;\n                std::cout \u003C\u003C \"Please enter your choice: \";\n\n                // Capture the user's nested choice\n                std::cin >> nestedChoice;\n\n                // If the player chooses to remain silent\n                if (nestedChoice == 1)\n                {\n                    std::cout \u003C\u003C \"Remaining silent, \" \u003C\u003C playerName \u003C\u003C \" hears whispers of the merfolk below, but nothing happens.\" \u003C\u003C std::endl;\n                }\n                // If the player chooses to sing along with the melody\n                else if (nestedChoice == 2)\n                {\n                    std::cout \u003C\u003C \"Singing along, a merfolk surfaces and gifts \" \u003C\u003C playerName\n                            \u003C\u003C \" a special blue gem as a token of appreciation for their voice.\"\n                            \u003C\u003C std::endl;\n                }\n                break;\n            // Option to exit the game\n            case 4:\n                exploring = false;\n                break;\n            // If 'choice' is not 1, 2, or 3, this block is executed.\n            default:\n                std::cout \u003C\u003C \"You did not enter a valid choice.\" \u003C\u003C std::endl;\n                continue; // Errors continue with the next loop iteration\n        }\n    }\n\n    // Return 0 to indicate successful execution\n    return 0;\n}\n\n```\n\n\nHere's what the build output looks like if we run `adventure.cpp` and the\nplayer heads to the Shimmering Lake.\n\n\n![adventure.cpp build output - the player is called sugaroverflow and heads\nto the Shimmering Lake and receives a\ngem](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/3.6.1-full-case-3-output.png){:\n.shadow}\n\n\n## Structuring the narrative: Characters\n\nOur player can now explore the world. Soon, our player will also be able to\nmeet people and collect objects. Before we can do that, let's organize the\nthings our player can do with creating some structure for the player\ncharacter.\n\n\nIn C++, a `struct` is used to group different data types. It's helpful in\ncreating a group of items that belong together, such as our player's\nattributes and inventory, into a single unit. `struct` objects are defined\nglobally, which means at top the file, before the `main() function.\n\n\nIf you start typing `struct Player {`, Code Suggestions will help you out\nwith a sample definition of a player struct.\n\n\n![adventure.cpp - Code Suggestions helps with setting up the struct\ndefinition for the\nplayer](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/4-player-struct-definition.png){:\n.shadow}\n\n\nAfter accepting this suggestion, you might find that Code Suggestions is\neager to define some functions to make this game more fun, such as hunting\nfor treasure.\n\n\n![adventure.cpp - Code Suggestions provides a suggestion for creating\nfunctions to hunt for\ntreasure.](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/4.1-player-struct-treasure-suggestion.png){:\n.shadow}\n\n\n```cpp\n\n// Define a structure for a Player in the game.\n\nstruct Player{\n    std::string name;  // The name of the player.\n    int health;        // The current health of the player.\n    int xp;            // Experience points gained by the player. Could be used for leveling up or other game mechanics.\n};\n\n```\n\n\nGiving the player experience points was not in my original plan for this\ntext adventure game, but Code Suggestions makes an interesting suggestion.\nWe could use `xp` for leveling up or for other game mechanics as our project\ngrows.\n\n\n`struct Player` provides a blueprint for creating a player and details the\nattributes that make up a player. To use our player in our code, we must\ninstantiate, or create, an object of the `Player` struct within our `main()`\nfunction. Objects in C++ are instances of structures that contain\nattributes. In our example, we're working with the `Player` struct, which\nhas attributes like name, health, and xp.\n\n\nAs you're creating a `Player` object, you might find that Code Suggestions\nwants to name the player \"John.\"\n\n\n![adventure.cpp - code suggestions suggests naming the new Player object\nJohn.](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/4.2-player-struct-instance-john.png){:\n.shadow}\n\n\n```cpp\n\nint main() {\n    // Create an instance of the Player struct\n    Player player;\n    player.health = 100; // Assign a default value for HP\n```\n\n\nInstead of naming our player \"John\" for everyone, we'll use the `Player`\nobject to set the attribute for name. When we want to interact with or\nmanipulate an attribute of an object, we use the dot operator `.`. The dot\noperator allows us to access specific members of the object. We can set the\nplayer's name using the dot operator with `player.name`.\n\n\nNote that we need to replace other mentions of `playerName` the variable\nwith `player.name`, which allows us to access the player object's name\ndirectly.\n\n\n* Search for all occurrences of the `playerName` variable, and replace it\nwith `player.name`.\n\n* Comment/Remove the unused `std::string playerName` variable after that.\n\n\nWhat your `adventure.cpp` will look like now:\n\n\n```cpp\n\n#include \u003Ciostream> // Include the I/O stream library for input and output\n\n\n// Define a structure for a Player in the game.\n\nstruct Player{\n    std::string name;  // The name of the player.\n    int health;        // The current health of the player.\n    int xp;            // Experience points gained by the player. Could be used for leveling up or other game mechanics.\n};\n\n\n// Main function, the starting point of the program\n\nint main()\n\n{\n    std::cout \u003C\u003C \"Welcome to the Dragon Realm!\" \u003C\u003C std::endl;\n\n    // Create an instance of the Player struct\n    Player player;\n    player.health = 100; // Assign a default value for HP\n\n    // Prompt the user to enter their player name\n    std::cout \u003C\u003C \"Please enter your name: \";\n    std::cin >> player.name;\n\n    // Display a personalized welcome message to the player with their name\n    std::cout \u003C\u003C \"Welcome \" \u003C\u003C player.name \u003C\u003C \" to The Dragon Realm!\" \u003C\u003C std::endl;\n\n    // Declare an int variable to capture the user's choice\n    int choice;\n    // Declare an int variable to capture the user's nested choice\n    int nestedChoice;\n\n    // Initialize a flag to control the loop and signify the player's intent to explore.\n    bool exploring = true;\n    // As long as the player wishes to keep exploring, this loop will run.\n    while(exploring) {\n\n        // If still exploring, ask the player where they want to go next\n        std::cout \u003C\u003C \"Where will \" \u003C\u003C player.name \u003C\u003C \" go next?\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"1. Moonlight Markets\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"2. Grand Library\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"3. Shimmering Lake\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"Please enter your choice: \";\n        // Update value of choice\n        std::cin >> choice;\n\n        // Respond based on the player's main choice\n        switch(choice) {\n            //  Handle the Moonlight Markets scenario\n            case 1:\n                std::cout \u003C\u003C \"You chose Moonlight Markets.\" \u003C\u003C std::endl;\n                break;\n            // Handle the Grand Library scenario.\n            case 2:\n                std::cout \u003C\u003C \"You chose Grand Library.\" \u003C\u003C std::endl;\n                break;\n            // Handle the Shimmering Lake scenario.\n            case 3:\n                std::cout \u003C\u003C player.name \u003C\u003C \" arrives at Shimmering Lake. It is one of the most beautiful lakes that\" \u003C\u003C player.name \u003C\u003C \" has seen. They hear a mysterious melody from the water. They can either: \" \u003C\u003C std::endl;\n                std::cout \u003C\u003C \"1. Stay quiet and listen\" \u003C\u003C std::endl;\n                std::cout \u003C\u003C \"2. Sing along with the melody\" \u003C\u003C std::endl;\n                std::cout \u003C\u003C \"Please enter your choice: \";\n\n                // Capture the user's nested choice\n                std::cin >> nestedChoice;\n\n                // If the player chooses to remain silent\n                if (nestedChoice == 1)\n                {\n                    std::cout \u003C\u003C \"Remaining silent, \" \u003C\u003C player.name \u003C\u003C \" hears whispers of the merfolk below, but nothing happens.\" \u003C\u003C std::endl;\n                }\n                // If the player chooses to sing along with the melody\n                else if (nestedChoice == 2)\n                {\n                    std::cout \u003C\u003C \"Singing along, a merfolk surfaces and gifts \" \u003C\u003C player.name\n                            \u003C\u003C \" a special blue gem as a token of appreciation for their voice.\"\n                            \u003C\u003C std::endl;\n                }\n                break;\n            // Option to exit the game\n            case 4:\n                exploring = false;\n                break;\n            // If 'choice' is not 1, 2, or 3, this block is executed.\n            default:\n                std::cout \u003C\u003C \"You did not enter a valid choice.\" \u003C\u003C std::endl;\n                continue; // Errors continue with the next loop iteration\n        }\n    }\n\n    // Return 0 to indicate successful execution\n    return 0;\n}\n\n```\n\n\n## Structuring the narrative: Items\n\nAn essential part of adventure games is a player's inventory - the\ncollection of items they acquire and use during their journey. For example,\nat Shimmering Lake, the player acquired a blue gem.\n\n\nLet's update our Player `struct` to include an inventory using an array. In\nC++, an `array` is a collection of elements of the same type that can be\nidentified by an index. When creating an array, you need to specify its type\nand size. Start by adding `std::string inventory` to the Player `struct`:\n\n\n![adventure.cpp - Code Suggestions shows us how to add an array of strings\nto the player struct to use as the players\ninventory](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/5-add-inventory-player-struct.png){:\n.shadow}\n\n\nYou might find that Code Suggestions wants our player to be able to carry\nsome gold, but we don't need that for now. Let's also add `int\ninventoryCount;` to keep track of the number of items in our player's\ninventory.\n\n\n![adventure.cpp - Code Suggestions shows us how to add an integer for\ninventoryCount to the player\nstruct](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/5.1-add-inventory-count-player-struct.png){:\n.shadow}\n\n\n```cpp\n\n// Define a structure for a Player in the game.\n\nstruct Player{\n    std::string name;  // The name of the player.\n    int health;        // The current health of the player.\n    int xp;            // Experience points gained by the player. Could be used for leveling up or other game mechanics.\n    std::string inventory[10];  // An array of strings for the player's inventory.\n    int inventoryCount = 0;  // The number of items in the player's inventory.\n};\n\n```\n\nIn our Player `struct`, we have defined an array for our inventory that can\nhold the names of 10 items (type:string, size: 10). As the player progresses\nthrough our story, we can assign new items to the inventory array based on\nthe player's actions using the array index.\n\n\nSometimes Code Suggestions gets ahead of me and tries to add more complexity\nto the game by suggesting that we need to create a `struct` for some\nMonsters. Maybe later, Code Suggestions!\n\n\n![adventure.cpp - Code Suggestions wants to add a struct for Monsters we can\nbattle](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/5.2-suggestion-gets-distracted-by-monsters.png\n\n){: .shadow}\n\n\nBack at the Shimmering Lake, the player received a special blue gem from the\nmerfolk. Let's update the code in `case 2` for the Shimmering Lake to add\nthe gem to our player's inventory.\n\n\nYou can start by accessing the player's inventory with `player.inventory`\nand Code Suggestions will help add the gem.\n\n\n![adventure.cpp - Code Suggestions shows us how to add a gem to the player's\ninventory using a post-increment operation and the inventory array from the\nstruct\nobject](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/5.3-add-gem-to-inventory.png){:\n.shadow}\n\n\n```cpp\n    // If the player chooses to sing along with the melody\n    else if (nestedChoice == 2)\n    {\n        std::cout \u003C\u003C \"Singing along, a merfolk surfaces and gifts \" \u003C\u003C player.name\n                \u003C\u003C \" a special blue gem as a token of appreciation for their voice.\"\n                \u003C\u003C std::endl;\n        player.inventory[player.inventoryCount] = \"Blue Gem\";\n        player.inventoryCount++;\n    }\n```\n\n\n* `player.inventory`: accesses the inventory attribute of the player object\n\n* `player.inventoryCount`: accesses the integer that keeps track of how many\nitems are currently in the player's inventory. This also represents the next\navailable index in our inventory array where an item can be stored.\n\n* `player.inventoryCount++`: increments the value of inventoryCount by 1.\nThis is a post-increment operation. We are adding “Blue Gem” to the next\navailable slot in the inventory array and incrementing the array for the\nnewly added item.\n\n\nOnce we've added something to our player's inventory, we may also want to be\nable to look at everything in the inventory. We can use a `for` loop to\niterate over the inventory array and display each item.\n\n\nIn C++, a `for` loop allows code to be repeatedly executed a specific number\nof times. It's different from the `while` loop we used earlier because the\n`while` executes its body based on a condition, whereas a `for` loop\niterates over a sequence or range, usually with a known number of times.\n\n\nAfter adding the gem to the player's inventory, let's display all the items\nit has. Try starting a for loop with `for ( ` to display the player's\ninventory and Code Suggestions will help you with the syntax.\n\n\n![adventure.cpp - Code Suggestions demonstrates how to write a for loop to\nloop through the players\ninventory](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/5.4-loop-over-players-inventory.png){:\n.shadow}\n\n\n```cpp\n\nstd::cout \u003C\u003C player.name \u003C\u003C \"'s Inventory:\" \u003C\u003C std::endl;\n\n// Loop through the player's inventory up to the count of items they have\n\nfor (int i = 0; i \u003C player.inventoryCount; i++)\n\n{\n    // Output the item in the inventory slot\n    std::cout \u003C\u003C \"- \" \u003C\u003C player.inventory[i] \u003C\u003C std::endl;\n}\n\n```\n\n\nA `for` loop consists of 3 main parts:\n\n\n* `int i = 0`: is the initialization where you set up your loop variable.\nHere, we start counting from 0.\n\n* `i \u003C player.inventoryCount`: is the condition we're looping on, our loop\nchecks if `i`, the current loop variable, is less than the number of items\nin our inventory. It will keep going until this is true.\n\n* `i++`: is the iteration. This updates the loop variable each time the loop\nruns.\n\n\nTo make sure that our loop doesn't encounter an error, let's add some error\nhandling to make sure the inventory is not empty when we try to output it.\n\n\n```\n\nstd::cout \u003C\u003C player.name \u003C\u003C \"'s Inventory:\" \u003C\u003C std::endl;\n\n// Loop through the player's inventory up to the count of items they have\n\nfor (int i = 0; i \u003C player.inventoryCount; i++)\n\n{\n    // Check if the inventory slot is not empty.\n    if (!player.inventory[i].empty())\n    {\n        // Output the item in the inventory slot\n        std::cout \u003C\u003C \"- \" \u003C\u003C player.inventory[i] \u003C\u003C std::endl;\n    }\n}\n\n```\n\n\nWith our progress so far, we've successfully established a persistent\n`while` loop for our adventure, handled decisions, crafted a `struct` for\nour player, and implemented a simple inventory system. Now, let's dive into\nthe next scenario, the Grand Library, applying the foundations we've\nlearned.\n\n\n**Async exercise**: Add more inventory items found in different locations.\n\n\nHere's what we have for `adventure.cpp` so far:\n\n\n```cpp\n\n#include \u003Ciostream> // Include the I/O stream library for input and output\n\n\n// Define a structure for a Player in the game.\n\nstruct Player{\n    std::string name;  // The name of the player.\n    int health;        // The current health of the player.\n    int xp;            // Experience points gained by the player. Could be used for leveling up or other game mechanics.\n    std::string inventory[10];  // An array of strings for the player's inventory.\n    int inventoryCount = 0;\n};\n\n\n// Main function, the starting point of the program\n\nint main()\n\n{\n    std::cout \u003C\u003C \"Welcome to the Dragon Realm!\" \u003C\u003C std::endl;\n\n    // Create an instance of the Player struct\n    Player player;\n    player.health = 100; // Assign a default value for HP\n\n    // Prompt the user to enter their player name\n    std::cout \u003C\u003C \"Please enter your name: \";\n    std::cin >> player.name;\n\n    // Display a personalized welcome message to the player with their name\n    std::cout \u003C\u003C \"Welcome \" \u003C\u003C player.name \u003C\u003C \" to The Dragon Realm!\" \u003C\u003C std::endl;\n\n    // Declare an int variable to capture the user's choice\n    int choice;\n    // Declare an int variable to capture the user's nested choice\n    int nestedChoice;\n\n    // Initialize a flag to control the loop and signify the player's intent to explore.\n    bool exploring = true;\n    // As long as the player wishes to keep exploring, this loop will run.\n    while(exploring) {\n\n        // If still exploring, ask the player where they want to go next\n        std::cout \u003C\u003C \"--------------------------------------------------------\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"Where will \" \u003C\u003C player.name \u003C\u003C \" go next?\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"1. Moonlight Markets\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"2. Grand Library\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"3. Shimmering Lake\" \u003C\u003C std::endl;\n        std::cout \u003C\u003C \"Please enter your choice: \";\n        // Update value of choice\n        std::cin >> choice;\n\n        // Respond based on the player's main choice\n        switch(choice) {\n            //  Handle the Moonlight Markets scenario\n            case 1:\n                std::cout \u003C\u003C \"You chose Moonlight Markets.\" \u003C\u003C std::endl;\n                break;\n            // Handle the Grand Library scenario.\n            case 2:\n                std::cout \u003C\u003C \"You chose Grand Library.\" \u003C\u003C std::endl;\n                break;\n            // Handle the Shimmering Lake scenario.\n            case 3:\n                std::cout \u003C\u003C player.name \u003C\u003C \" arrives at Shimmering Lake. It is one of the most beautiful lakes that\" \u003C\u003C player.name \u003C\u003C \" has seen. They hear a mysterious melody from the water. They can either: \" \u003C\u003C std::endl;\n                std::cout \u003C\u003C \"1. Stay quiet and listen\" \u003C\u003C std::endl;\n                std::cout \u003C\u003C \"2. Sing along with the melody\" \u003C\u003C std::endl;\n                std::cout \u003C\u003C \"Please enter your choice: \";\n\n                // Capture the user's nested choice\n                std::cin >> nestedChoice;\n\n                // If the player chooses to remain silent\n                if (nestedChoice == 1)\n                {\n                    std::cout \u003C\u003C \"Remaining silent, \" \u003C\u003C player.name \u003C\u003C \" hears whispers of the merfolk below, but nothing happens.\" \u003C\u003C std::endl;\n                }\n                // If the player chooses to sing along with the melody\n                else if (nestedChoice == 2)\n                {\n                    std::cout \u003C\u003C \"Singing along, a merfolk surfaces and gifts \" \u003C\u003C player.name\n                            \u003C\u003C \" a special blue gem as a token of appreciation for their voice.\"\n                            \u003C\u003C std::endl;\n                    player.inventory[player.inventoryCount] = \"Blue Gem\";\n                    player.inventoryCount++;\n\n                    std::cout \u003C\u003C player.name \u003C\u003C \"'s Inventory:\" \u003C\u003C std::endl;\n                    // Loop through the player's inventory up to the count of items they have\n                    for (int i = 0; i \u003C player.inventoryCount; i++)\n                    {\n                        // Check if the inventory slot is not empty.\n                        if (!player.inventory[i].empty())\n                        {\n                            // Output the item in the inventory slot\n                            std::cout \u003C\u003C \"- \" \u003C\u003C player.inventory[i] \u003C\u003C std::endl;\n                        }\n                    }\n\n                }\n                break;\n            // Option to exit the game\n            case 4:\n                exploring = false;\n                break;\n            // If 'choice' is not 1, 2, or 3, this block is executed.\n            default:\n                std::cout \u003C\u003C \"You did not enter a valid choice.\" \u003C\u003C std::endl;\n                continue; // Errors continue with the next loop iteration\n        }\n    }\n\n    // Return 0 to indicate successful execution\n    return 0;\n}\n\n```\n\n\n![adventure.cpp - A full output of the game at the current state - our\nplayer sugaroverflow visits the Lake, receives the gem, adds it to their\ninventory, and we display the inventory before returning to the\nloop](https://about.gitlab.com/images/blogimages/2023-08-21-building-a-text-adventure-using-cplusplus-and-code-suggestions/5.5-full-output-shimmering-lake.png){:\n.shadow}\n",[496,717,1016,9,827],"workflow",{"slug":1018,"featured":6,"template":698},"building-a-text-adventure-using-cplusplus-and-code-suggestions","content:en-us:blog:building-a-text-adventure-using-cplusplus-and-code-suggestions.yml","Building A Text Adventure Using Cplusplus And Code Suggestions","en-us/blog/building-a-text-adventure-using-cplusplus-and-code-suggestions.yml","en-us/blog/building-a-text-adventure-using-cplusplus-and-code-suggestions",{"_path":1024,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1025,"content":1031,"config":1042,"_id":1044,"_type":14,"title":1045,"_source":16,"_file":1046,"_stem":1047,"_extension":19},"/en-us/blog/building-gitlab-with-gitlab-a-multi-region-service-to-deliver-ai-features",{"title":1026,"description":1027,"ogTitle":1026,"ogDescription":1027,"noIndex":6,"ogImage":1028,"ogUrl":1029,"ogSiteName":686,"ogType":687,"canonicalUrls":1029,"schema":1030},"Building GitLab with GitLab: A multi-region service to deliver AI features","Discover how we built our first multi-region deployment for teams at GitLab using the platform's many features, helping create a frictionless developer experience for GitLab Duo users.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098664/Blog/Hero%20Images/Blog/Hero%20Images/building-gitlab-with-gitlab-no-type_building-gitlab-with-gitlab-no-type.png_1750098663794.png","https://about.gitlab.com/blog/building-gitlab-with-gitlab-a-multi-region-service-to-deliver-ai-features","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Building GitLab with GitLab: A multi-region service to deliver AI features\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Chance Feick\"},{\"@type\":\"Person\",\"name\":\"Sam Wiskow\"}],\n        \"datePublished\": \"2024-09-12\",\n      }",{"title":1026,"description":1027,"authors":1032,"heroImage":1028,"date":1035,"body":1036,"category":909,"tags":1037},[1033,1034],"Chance Feick","Sam Wiskow","2024-09-12","For GitLab Duo, real-time AI-powered capabilities like [Code\nSuggestions](https://about.gitlab.com/solutions/code-suggestions/) need\nlow-latency response times for a frictionless developer experience. Users\ndon’t want to interrupt their flow and wait for a code suggestion to show\nup. To ensure GitLab Duo can provide the right suggestion at the right time\nand meet high performance standards for critical AI infrastructure, GitLab\nrecently launched our first multi-region service to deliver AI features.\n\n\nIn this article, we will cover the benefits of multi-region services, how we\nbuilt an internal platform codenamed ‘Runway’ for provisioning and deploying\nmulti-region services using GitLab features, and the lessons learned\nmigrating to multi-region in production.\n\n\n## Background on the project\n\n\nRunway is GitLab’s internal platform as a service (PaaS) for provisioning,\ndeploying, and operating containerized services. Runway's purpose is to\nenable GitLab service owners to self-serve infrastructure needs with\nproduction readiness out of the box, so application developers can focus on\nproviding value to customers. As part of [our corporate value of\ndogfooding](https://handbook.gitlab.com/handbook/values/#results), the first\niteration was built in 2023 by the Infrastructure department on top of core\nGitLab capabilities, such as continuous integration/continuous delivery\n([CI/CD](https://about.gitlab.com/topics/ci-cd/)), environments, and\ndeployments.\n\n\nBy establishing automated GitOps best practices, Runway services use\ninfrastructure as code (IaC), merge requests (MRs), and CI/CD by default.\n\n\nGitLab Duo is primarily powered by [AI\nGateway](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist),\na satellite service written in Python outside of GitLab’s modular monolith\nwritten in Ruby. In cloud computing, a region is a geographical location of\ndata centers operated by cloud providers.\n\n\n## Defining a multi-region strategy\n\n\nDeploying in a single region is a good starting point for most services, but\ncan come with downsides when you are trying to reach a global audience.\nUsers who are geographically far from where your service is deployed may\nexperience different levels of service and responsiveness than those who are\ncloser. This can lead to a poor user experience, even if your service is\nwell built in all other respects.\n\n\nFor AI Gateway, it was important to meet global customers wherever they are\nlocated, whether on GitLab.com or self-managed instances using Cloud\nConnector. When a developer is deciding to accept or reject a code\nsuggestion, milliseconds matter and can define the user experience.\n\n\n### Goals\n\n\nMulti-region deployments require more infrastructure complexity, but for use\ncases where latency is a core component of the user experience, the benefits\noften outweigh the downsides. First, multi-region deployments offer\nincreased responsiveness to the user. By serving requests from locations\nclosest to end users, latency can be significantly reduced. Second,\nmulti-region deployments provide greater availability. With fault tolerance,\nservices can fail over during a regional outage. There is a much lower\nchance of a service failing completely, meaning users should not be\ninterrupted even in partial failures.\n\n\nBased on our goals for performance and availability, we used this\nopportunity to create a scalable multi-region strategy in Runway, which is\nbuilt leveraging GitLab features.\n\n\n### Architecture\n\n\nIn SaaS platforms, GitLab.com’s infrastructure is hosted on Google Cloud\nPlatform (GCP). As a result, Runway’s first supported platform runtime is\nCloud Run. The initial workloads deployed on Runway are stateless satellite\nservices (e.g., AI Gateway), so Cloud Run services are a good fit that\nprovide a clear migration path to more complex and flexible platform\nruntimes, e.g. Kubernetes.\n\n\nBuilding Runway on top of GCP Cloud Run using GitLab has allowed us to\niterate and tease out the right level of abstractions for service owners as\npart of a platform play in the Infrastructure department.\n\n\nTo serve traffic from multiple regions in Cloud Run, the multi-region\ndeployment strategy must support global load balancing, and the provisioning\nand configuration of regional resources. Here’s a simplified diagram of the\nproposed architecture in GCP:\n\n\n![simplified diagram of the proposed architecture in\nGCP](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098671/Blog/Content%20Images/Blog/Content%20Images/image7_aHR0cHM6_1750098671612.png)\n\n\nBy replicating Cloud Run services across multiple regions and configuring\nthe existing global load balancing with serverless network endpoint group\n(NEG) backends, we’re able to serve traffic from multiple regions. For the\nremainder of the article, we’ll focus less on specifics of Cloud Run and\nmore on how we’re building with GitLab.\n\n\n## Building a multi-region platform with GitLab\n\n\nNow that you have context about Runway, let's walk through how to build a\nmulti-region platform using GitLab features.\n\n\n### Provision\n\n\nWhen building an internal platform, the first challenge is provisioning\ninfrastructure for a service. In Runway, Provisioner is the component that\nis responsible for maintaining a service inventory and managing IaC for GCP\nresources using Terraform.\n\n\nTo provision a service, an application developer will open an MR to add a\nservice project to the inventory using git, and Provisioner will create\nrequired resources, such as service accounts and identity and access\nmanagement policies. When building this functionality with GitLab, Runway\nleverages [OpenID Connect (OIDC) with GPC Workload Identity\nFederation](https://docs.gitlab.com/ee/ci/cloud\\_services/google\\_cloud/)\nfor managing IaC.\n\n\nAdditionally, Provisioner will create a deployment project for each service\nproject. The purpose of creating separate projects for deployments is to\nensure the [principle of least\nprivilege](https://about.gitlab.com/blog/the-ultimate-guide-to-least-privilege-access-with-gitlab/)\nby authenticating as a GCP service account with restricted permissions.\nRunway leverages the [Projects\nAPI](https://docs.gitlab.com/ee/api/projects.html) for creating projects\nwith [Terraform\nprovider](https://registry.terraform.io/providers/gitlabhq/gitlab/latest/docs).\n\n\nFinally, Provisioner defines variables in the deployment project for the\nservice account, so that deployment CI jobs can authenticate to GCP. Runway\nleverages [CI/CD variables](https://docs.gitlab.com/ee/ci/variables/) and\n[Job Token\nallowlist](https://docs.gitlab.com/ee/ci/jobs/ci\\_job\\_token.html\\#add-a-group-or-project-to-the-job-token-allowlist)\nto handle authentication and authorization.\n\n\nHere’s a simplified example of provisioning a multi-region service in the\nservice inventory:\n\n\n```\n\n{\n  \"inventory\": [\n    {\n      \"name\": \"example-service\",\n      \"project_id\": 46267196,\n      \"regions\": [\n        \"europe-west1\",\n        \"us-east1\",\n        \"us-west1\"\n      ]\n    }\n  ]\n}\n\n```\n\n\nOnce provisioned, a deployment project and necessary infrastructure will be\ncreated for a service.\n\n\n### Configure\n\n\nAfter a service is provisioned, the next challenge is the configuration for\na service. In Runway,\n[Reconciler](https://gitlab.com/gitlab-com/gl-infra/platform/runway/runwayctl)\nis a component that is responsible for configuring and deploying services by\naligning the actual state with the desired state using Golang and Terraform.\n\n\nHere’s a simplified example of an application developer configuring GitLab\nCI/CD in their service project:\n\n\n```\n\n# .gitlab-ci.yml\n\nstages:\n  - validate\n  - runway_staging\n  - runway_production\n\ninclude:\n  - project: 'gitlab-com/gl-infra/platform/runway/runwayctl'\n    file: 'ci-tasks/service-project/runway.yml'\n    inputs:\n      runway_service_id: example-service\n      image: \"$CI_REGISTRY_IMAGE/${CI_PROJECT_NAME}:${CI_COMMIT_SHORT_SHA}\"\n      runway_version: v3.22.0\n\n# omitted for brevity\n\n```\n\n\nRunway provides sane default values for configuration that are based on our\nexperience in delivering stable and reliable features to customers.\nAdditionally, service owners can configure infrastructure using a service\nmanifest file hosted in a service project. The service manifest uses JSON\nSchema for validation. When building this functionality with GitLab, Runway\nleverages [Pages](https://docs.gitlab.com/ee/user/project/pages/) for schema\ndocumentation.\n\n\nTo deliver this part of the platform, Runway leverages [CI/CD\ntemplates](https://docs.gitlab.com/ee/development/cicd/templates.html),\n[Releases](https://docs.gitlab.com/ee/user/project/releases/), and\n[Container\nRegistry](https://docs.gitlab.com/ee/user/packages/container\\_registry/) for\nintegrating with service projects.\n\n\nHere’s a simplified example of a service manifest:\n\n\n```\n\n# .runway/runway-production.yml\n\napiVersion: runway/v1\n\nkind: RunwayService\n\nspec:\n container_port: 8181\n regions:\n   - us-east1\n   - us-west1\n   - europe-west1\n\n# omitted for brevity\n\n```\n\n\nFor multi-region services, Runway injects an environment variable into the\ncontainer instance runtime, e.g. RUNWAY\\_REGION, so application developers\nhave the context to make any downstream dependencies regionally-aware, e.g.\nVertex AI API.\n\n\nOnce configured, a service project will be integrated with a deployment\nproject.\n\n\n### Deploy\n\n\nAfter a service project is configured, the next challenge is deploying a\nservice. In Runway, Reconciler handles this by triggering a deployment job\nin the deployment project when an MR is merged to the main branch. When\nbuilding this functionality with GitLab, Runway leverages [Trigger\nPipelines](https://docs.gitlab.com/ee/ci/triggers/) and [Multi-Project\nPipelines](https://docs.gitlab.com/ee/ci/pipelines/downstream\\_pipelines.html\\#multi-project-pipelines)\nto trigger jobs from service project to deployment project.\n\n\n![trigger jobs from service project to deployment\nproject](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098672/Blog/Content%20Images/Blog/Content%20Images/image5_aHR0cHM6_1750098671612.png)\n\n\nOnce a pipeline is running in a deployment project, it will be deployed to\nan environment. By default, Runway will provision staging and production\nenvironments for all services. At this point, Reconciler will apply any\nTerraform resource changes for infrastructure. When building this\nfunctionality with GitLab, Runway leverages\n[Environments/Deployments](https://docs.gitlab.com/ee/ci/environments/) and\n[GitLab-managed Terraform\nstate](https://docs.gitlab.com/ee/user/infrastructure/iac/terraform\\_state.html)\nfor each service.\n\n\n![Reconciler applies any Terraform resource changes for\ninfrastructure](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098672/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098671614.png)\n\n\nRunway provides default application metrics for services. Additionally,\ncustom metrics can be used by enabling a sidecar container with\nOpenTelemetry Collector configured to scrape Prometheus and remote write to\nMimir. By providing observability out of the box, Runway is able to bake\nmonitoring into CI/CD pipelines.\n\n\nExample scenarios include gradual rollouts for blue/green deployments,\npreventing promotions to production when staging is broken, or automatically\nrolling back to previous revision when elevated error rates occur in\nproduction.\n\n\n![Runway bakes monitoring into CI/CD\npipelines](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098672/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098671615.png)\n\n\nOnce deployed, environments will serve the latest revision of a service. At\nthis point, you should have a good understanding of some of the challenges\nthat will be encountered, and how to solve them with GitLab features.\n\n\n## Migrating to multi-region in production\n\n\nAfter extending Runway components to support multi-region in Cloud Run, the\nfinal challenge was migrating from AI Gateway’s single-region deployment in\nproduction with zero downtime. Today, teams using Runway to deploy their\nservices can self-serve on regions making a multi-region deployment just as\nsimple as a single-region deployment. \n\n\nWe were able to iterate on building multi-region functionality without\nimpacting existing infrastructure by using semantic versioning for Runway.\nNext, we’ll share some learnings from the migration that may inform how to\noperate services for an internal multi-region platform.\n\n\n### Dry run deployments\n\n\nIn Runway, Reconciler will apply Terraform changes in CI/CD. The trade-off\nis that plans cannot be verified in advance, which could risk inadvertently\ndestroying or misconfiguring production infrastructure. To solve this\nproblem, Runway will perform a “dry run” deployment for MRs.\n\n\n![\"Dry run\"\ndeployment](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098672/Blog/Content%20Images/Blog/Content%20Images/image6_aHR0cHM6_1750098671616.png)\n\n\nFor migrating AI Gateway, dry run deployments increased confidence and\nhelped mitigate risk of downtime during rollout. When building an internal\nplatform with GitLab, we recommend supporting dry run deployments from the\nstart.\n\n\n### Regional observability\n\n\nIn Runway, existing observability was aggregated by assuming a single-region\ndeployment. To solve this problem, Runway observability was retrofitted to\ninclude a new region label for Prometheus metrics.\n\n\nOnce metrics were retrofitted, we were able to introduce service level\nindicators (SLIs) for both regional Cloud Run services and global load\nbalancing. Here’s an example dashboard screenshot for a general Runway\nservice:\n\n\n![dashboard screenshot for a general Runway\nservice](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098672/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750098671617.png)\n\n\n***Note:** Data is not actual production data and is only for illustration\npurposes.*\n\n\nAdditionally, we were able to update our service level objectives (SLOs) to\nsupport regions. As a result, service owners could be alerted when a\nspecific region experiences an elevated error rate, or increase in response\ntimes.\n\n\n![screenshot of\nalerts](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098672/Blog/Content%20Images/Blog/Content%20Images/image4_aHR0cHM6_1750098671617.png)\n\n\n***Note:** Data is not actual production data and is only for illustration\npurposes.*\n\n\nFor migrating AI Gateway, regional observability increased confidence and\nhelped provide more visibility into new infrastructure. When building an\ninternal platform with GitLab, we recommend supporting regional\nobservability from the start.\n\n\n### Self-service regions\n\n\nThe Infrastructure department successfully performed the initial migration\nof multi-region support for AI Gateway in production with zero downtime.\nGiven the risk associated with rolling out a large infrastructure migration,\nit was important to ensure the service continued working as expected.\n\n\nShortly afterwards, service owners began self-serving additional regions to\nmeet the growth of customers. At the time of writing, [GitLab\nDuo](https://about.gitlab.com/gitlab-duo/) is available in six regions\naround the globe and counting. Service owners are able to configure the\ndesired regions, and Runway will provide guardrails along the way in a\nscalable solution.\n\n\nAdditionally, three other internal services have already started using\nmulti-region functionality on Runway. Application developers have entirely\nself-served functionality, which validates that we’ve provided a good\nplatform experience for service owners. For a platform play, a scalable\nsolution like Runway is considered a good outcome since the Infrastructure\ndepartment is no longer a blocker.\n\n\n## What’s next for Runway\n\n\nBased on how quickly we could iterate to provide results for customers, the\nSaaS Platforms department has continued to invest in Runway. We’ve grown the\nRunway team with additional contributors, started evolving the platform\nruntime (e.g. Google Kubernetes Engine), and continue dogfooding with\ntighter integration in the product.\n\n\nIf you’re interested in learning more, feel free to check out\n[https://gitlab.com/gitlab-com/gl-infra/platform/runway](https://gitlab.com/gitlab-com/gl-infra/platform/runway).\n\n\n## More Building GitLab with GitLab\n\n- [Why there is no MLOps without\nDevSecOps](https://about.gitlab.com/blog/there-is-no-mlops-without-devsecops/)\n\n- [Stress-testing Product\nAnalytics](https://about.gitlab.com/blog/building-gitlab-with-gitlab-stress-testing-product-analytics/)\n\n- [Web API Fuzz\nTesting](https://about.gitlab.com/blog/building-gitlab-with-gitlab-api-fuzzing-workflow/)\n\n- [How GitLab.com inspired\nDedicated](https://about.gitlab.com/blog/building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated/)\n\n- [Expanding our security certification\nportfolio](https://about.gitlab.com/blog/building-gitlab-with-gitlab-expanding-our-security-certification-portfolio/)\n",[109,826,825,1038,827,1039,1040,1041,9,717],"inside GitLab","performance","google","git",{"slug":1043,"featured":91,"template":698},"building-gitlab-with-gitlab-a-multi-region-service-to-deliver-ai-features","content:en-us:blog:building-gitlab-with-gitlab-a-multi-region-service-to-deliver-ai-features.yml","Building Gitlab With Gitlab A Multi Region Service To Deliver Ai Features","en-us/blog/building-gitlab-with-gitlab-a-multi-region-service-to-deliver-ai-features.yml","en-us/blog/building-gitlab-with-gitlab-a-multi-region-service-to-deliver-ai-features",{"_path":1049,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1050,"content":1056,"config":1063,"_id":1065,"_type":14,"title":1066,"_source":16,"_file":1067,"_stem":1068,"_extension":19},"/en-us/blog/building-gitlab-with-gitlab-stress-testing-product-analytics",{"title":1051,"description":1052,"ogTitle":1051,"ogDescription":1052,"noIndex":6,"ogImage":1053,"ogUrl":1054,"ogSiteName":686,"ogType":687,"canonicalUrls":1054,"schema":1055},"Building GitLab with GitLab: Stress-testing Product Analytics","We put Product Analytics through its paces internally to prep it for Beta. Find out what that entailed and how it led to feature improvements.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659740/Blog/Hero%20Images/building-gitlab-with-gitlab-no-type.png","https://about.gitlab.com/blog/building-gitlab-with-gitlab-stress-testing-product-analytics","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Building GitLab with GitLab: Stress-testing Product Analytics\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"James Heimbuck\"},{\"@type\":\"Person\",\"name\":\"Sam Kerr\"}],\n        \"datePublished\": \"2023-12-14\",\n      }",{"title":1051,"description":1052,"authors":1057,"heroImage":1053,"date":1060,"body":1061,"category":10,"tags":1062},[1058,1059],"James Heimbuck","Sam Kerr","2023-12-14","To best understand how your features being developed and shipped are helping you meet your goals, you need data. The previously announced [Product Analytics feature set](https://about.gitlab.com/blog/introducing-product-analytics-in-gitlab/) helps our customers do just that by providing tools to instrument code and process and visualize the data – all within GitLab.\n\n## Privacy first\n\nWe know customer privacy is a big concern for our customers and our customer's customers. As we said in our [announcement blog](https://about.gitlab.com/blog/introducing-product-analytics-in-gitlab/#our-continued-commitment-to-user-privacy):\n\n\u003Cp>\u003Ccenter>\"Product Analytics is designed to honor commonly recognized opt-out signals and we are designing Product Analytics to give you full control over the data being collected on a cluster managed by GitLab or your own.\"\u003C/center>\u003C/p>\n\nNothing about that approach has changed and it is too important not to mention again.\n\n## Customer Zero and the biggest customer\n\nWe are progressing quickly towards the open beta for Product Analytics. We are currently feature-complete for the beta with the managed product analytics stack, [five existing SDKs for instrumentation](https://docs.gitlab.com/ee/user/product_analytics/#instrument-a-gitlab-project), [default dashboards](https://docs.gitlab.com/ee/user/analytics/analytics_dashboards.html#product-analytics), and the recently released  improved Dashboard and Visualization Designer experiences. We are also learning more about what problems our internal users still have that they cannot solve with Product Analytics.\n\nAs we prepare for the Beta release of Product Analytics, it is important for us to know how the Managed Product Analytics stack will stand up to a bigger event load than we are getting from the initial customers and internal users. With our commitment to dogfooding, adding more internal projects was the obvious answer, so we worked with more internal teams to add instrumentation for the Metrics Dictionary and [GitLab Design System](https://design.gitlab.com/) sites.\n\nInstrumenting internal projects gave us additional feedback about the setup of Product Analytics and the usefulness of the Audience and Behavior Dashboards, showing how many users were visiting and what pages they visited. These gave us great insights into the usefulness of Product Analytics, but did not provide the volume of events we needed to really stress test Product Analytics at the scale we wanted. \n\n![product-analytics-default-dashboard-list](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683252/Blog/Content%20Images/product-analytics-default-dashboard-list.png)\n\nAt the same time the Analytics Instrumentation team was hard at work developing an event framework to make instrumentation easier for GitLab developers. This lets the GitLab teams create new features and update existing ones faster to understand how changes impact our users. This also made it much easier and faster to add Product Analytics to GitLab.com, which provided the event volume that would stress test the Product Analytics stack so we could validate our assumptions.\n\nOnce fully enabled, with all page views and events going to the Managed Product Analytics stack, we saw a 17x increase in load above all other internally instrumented projects, receiving over 20 million events a day. That is a lot of events!\n\nBy instrumenting GitLab.com, we were able to see the stress cracks in our infrastructure _before_ introducing the features to users in our Beta. We were able to validate our scaling strategies, identify and resolve query performance concerns, improve the onboarding experience for our upcoming Beta program, and plan future improvements as we work towards [general availability](https://gitlab.com/groups/gitlab-org/-/epics/9902).\n\nWe have also proved to ourselves that Product Analytics can stand up to future customer load without making customers suffer through outages or slowness as we make the stack better.\n\n## What’s next for Product Analytics\n\nThroughout the internal release and the experiment phase, we have been talking to customers about what is and is not working with Product Analytics, especially the [built-in dashboards](https://docs.gitlab.com/ee/user/analytics/analytics_dashboards.html#product-analytics). From that feedback we have a number of improvements in mind that can't all fit here but check out our [Product Analytics direction page](https://about.gitlab.com/direction/monitor/product-analytics/#what-is-next-for-us-and-why) to see the latest on what improvements are coming next.\n\nTalking directly with users of Product Analytics is also informing the next iterations of other features like [Customizable Dashboards](https://gitlab.com/groups/gitlab-org/-/epics/8574) and [Visualization Designer](https://gitlab.com/groups/gitlab-org/-/epics/9386). The team is also exploring ways to [leverage AI](https://gitlab.com/groups/gitlab-org/-/epics/10335) to make it easier to find and understand Product Analytics data. \n\n## Share your feedback\n\nIt is an exciting time in product analytics and we cannot wait for you to try the feature out yourself! You can add ideas or comments to our [feedback issue](https://gitlab.com/gitlab-org/gitlab/-/issues/391970). We look forward to hearing from you!\n\n## Read more \"Building GitLab with GitLab\"\n\n- [Building GitLab with GitLab: How GitLab.com inspired Dedicated](https://about.gitlab.com/blog/building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated/)\n- [Building GitLab with GitLab: Web API Fuzz Testing](https://about.gitlab.com/blog/building-gitlab-with-gitlab-api-fuzzing-workflow/)\n",[9,848,1039,1038],{"slug":1064,"featured":91,"template":698},"building-gitlab-with-gitlab-stress-testing-product-analytics","content:en-us:blog:building-gitlab-with-gitlab-stress-testing-product-analytics.yml","Building Gitlab With Gitlab Stress Testing Product Analytics","en-us/blog/building-gitlab-with-gitlab-stress-testing-product-analytics.yml","en-us/blog/building-gitlab-with-gitlab-stress-testing-product-analytics",{"_path":1070,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1071,"content":1076,"config":1085,"_id":1087,"_type":14,"title":1088,"_source":16,"_file":1089,"_stem":1090,"_extension":19},"/en-us/blog/building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated",{"title":1072,"description":1073,"ogTitle":1072,"ogDescription":1073,"noIndex":6,"ogImage":1053,"ogUrl":1074,"ogSiteName":686,"ogType":687,"canonicalUrls":1074,"schema":1075},"Building GitLab with GitLab: How GitLab.com inspired Dedicated","Learn how the multi-tenancy SaaS solution, GitLab.com, influenced the design of the single-tenancy SaaS, GitLab Dedicated.","https://about.gitlab.com/blog/building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Building GitLab with GitLab: How GitLab.com inspired Dedicated\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Andrew Newdigate\"},{\"@type\":\"Person\",\"name\":\"Craig Miskell\"},{\"@type\":\"Person\",\"name\":\"John Coghlan\"}],\n        \"datePublished\": \"2023-08-03\",\n      }",{"title":1072,"description":1073,"authors":1077,"heroImage":1053,"date":1081,"body":1082,"category":909,"tags":1083},[1078,1079,1080],"Andrew Newdigate","Craig Miskell","John Coghlan","2023-08-03","\nEarlier this year, we announced [the general availability of GitLab Dedicated](https://about.gitlab.com/blog/gitlab-dedicated-available/), our single-tenancy software-as-a-service (SaaS) offering. Dedicated, which addresses the needs of customers with stringent compliance requirements while maintaining speed, efficiency, and security, was developed from the lessons we learned building and using GitLab.com, our multi-tenancy model. Although there is overlap in how we manage both platforms, such as the same service-level monitoring stack, there were significant considerations that sparked the need for new design decisions, including how we approach automation, databases, monitoring, and availability. In this blog, we share some of those decision points and their outcomes.\n\n## GitLab platform options\nBefore we dive into the evolution of GitLab Dedicated, let’s level-set on GitLab’s [portfolio of platform models](https://docs.gitlab.com/ee/subscriptions/choosing_subscription.html#choose-a-subscription):\n- GitLab.com, a.k.a. multi-tenant GitLab SaaS on our pricing page and in our documentation\n- GitLab Dedicated, single-tenant SaaS that satisfies compliance requirements such as data residency, isolation, and private networking\n- GitLab self-managed, in which customers install, administer, and maintain their own GitLab instance\n\nEach method meets the different needs of our wide range of customers and requires a unique approach for how we create, package, and deploy the application.\n\nWhile both GitLab.com and Dedicated are SaaS-based, there are key differences between the two. The multi-tenant GitLab.com is the largest hosted instance of GitLab and services thousands of customers and millions of users. Because the platform's reliability is critical to so many customers and because of the iterative nature of how GitLab.com was built, decisions have been made along the way that are unique to the scale of this specific instance.\n\nIn contrast, GitLab Dedicated is a single-tenant SaaS application that is hosted by GitLab in the customer's region of choice (GitLab.com is hosted in the U.S.). While still providing a GitLab-managed SaaS solution for our customers, Dedicated instances are fully isolated from one another, running on a platform that automates the configuration and provisioning of the instances, along with automating as many of the day-two operations as possible, such as maintenance, monitoring, and optimization.\n\nHere are some examples of how Dedicated has used the blueprint of GitLab.com.\n\n## Improved automated deployments\nGitLab.com is a permanent installation with a great deal of history, having evolved significantly since it was first developed. Originally, it was deployed on a single instance in Amazon AWS, before migrating to Microsoft Azure, where it continued to scale out. From Azure, it migrated to its current cloud, Google Cloud Platform. Since then, many customer workloads have [migrated into Kubernetes](https://about.gitlab.com/blog/year-of-kubernetes/) and are supported by the Google Kubernetes Engine ([GKE](https://cloud.google.com/kubernetes-engine)).\n\nWith GitLab Dedicated, we're building smaller instances that rely on automation, repeatability, and deterministic environments. All customer tenant GitLab instance operations must be 100% automated, including provisioning, upgrades, scaling, configuration changes, and any other routine operations. The stack relies heavily on the GitLab Environment Toolkit ([GET](https://gitlab.com/gitlab-org/gitlab-environment-toolkit/-/blob/main/docs/environment_advanced_hybrid.md)) Cloud Native Hybrid, which uses the GitLab Helm charts for stateless workloads (e.g., Rails) and Omnibus for deployments to VMs (e.g., Gitaly). GET helps with the deployments targeting [reference architectures](https://docs.gitlab.com/ee/administration/reference_architectures/) and coordinating the provisioning of cloud resources, including compute instances, Kubernetes clusters, managed Postgres databases and more.\n\nAs much as GET automates, it has a certain amount of required setup, which is acceptable to perform manually for one-off or otherwise long-lived deployments, but in order to scale Dedicated we also had to automate that process, which we did with Terraform. Because this was a greenfield approach, we were able to be particularly careful with privileges. Our current cloud deployment target is AWS, so we developed a detailed identity and access management ([IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)) policy to grant each stage of deployment only the strictly necessary access. We also use IAM role assumption from trusted workloads in a central AWS account to eliminate the need for explicit credentials.  \n\nDeployments follow this process in order:\n- An account creation job running from a trusted location creates a fresh AWS account in an [AWS Organization](https://docs.aws.amazon.com/organizations/index.html), placing it in the correct Organizational Unit to automatically have a [CloudFormation StackSet](https://docs.aws.amazon.com/organizations/latest/userguide/services-that-can-integrate-cloudformation.html) applied, with ongoing updates handled by AWS when needed. This allows us to operate the entire lifecycle of the tenant account using IAM Role Assumption rather than generating and storing static IAM credentials.\n- Prepare stage sets up a fresh AWS account ready to receive a deployment; the privileges are quite high powered, but still limited to the necessary areas, including creating the next role.  \n- Onboard stage creates some high-level resources and otherwise does the setup that GET requires to be able to run, including creating the roles for the next stages with their own limited privileges.  \n- Provision stage is mostly about running GET Terraform and creating the compute and storage resources onto which GitLab will be deployed, with a few additions for our specific needs.  \n- Configure stage runs to deploy the GitLab application onto the resources created earlier. At its core, this is the GET Ansible stage, but it includes our own Terraform wrapper as well to handle our specific needs.\n\nOnce these stages complete, a fully deployed GitLab instance is ready to go.  \n\nConfiguration changes and GitLab upgrades execute the same set of stages, ensuring everything is still configured correctly and applying any pending changes. In the early days of GitLab Dedicated this was done in GitLab CI/CD pipelines operating on GitLab.com, with the tenant descriptions as JSON files in a repository, which was an effective and simple place to start.  \n\nHowever, this multi-stage deployment is now managed by [Switchboard](https://about.gitlab.com/direction/saas-platforms/switchboard/), a portal we built specifically for GitLab Dedicated. Switchboard is a bespoke Rails application, which will be the single source of truth for configuration, accessible by customers to manage customer-facing settings, as well as GitLab Dedicated staff for general management. Switchboard will be responsible for automating regular upgrades, including gradual rollouts across the fleet of Dedicated instances.\n\n## Databases geared towards the needs of single tenancy\nGitLab.com uses self-managed Postgres and Redis. For GitLab Dedicated, we wanted to leverage AWS’s managed services as much as possible. Examples include RDS, Elasticache, and OpenSearch, the AWS Elasticsearch managed service. Some of these services may not always be able to support GitLab.com-scale platforms, but they handle the traffic of a single-tenant instance well and provide reliable failovers and ongoing maintenance with no effort on our part.\n\n## Monitoring aligned with strict compliance needs\nThe observability stack for GitLab Dedicated relies on the expertise we gained from building GitLab.com. The monitoring, logging, and availability infrastructure is all maintained within the customer's AWS account, nothing is shared. We receive low-context alerts from these private systems. They serve as a mechanism to direct us to the customer account so we can review what is going on and triage the underlying issues if needed. This is helpful with regulators and compliance as nothing can leak because it doesn't leave the system.\n\nWhile Dedicated and GitLab.com share much of the same monitoring stack, Dedicated instances have tended to reveal different issues within our application. This is due to GitLab.com being a multi-tenant instance, while GitLab Dedicated instances are single-tenant. \n\nThink of the adage, \"[Your 9s are not my 9s](https://rachelbythebay.com/w/2019/07/15/giant/).\" In a platform at the scale of GitLab.com, a subset of users who encounter an issue in part of the application may be a very small percentage of the overall user base. The small impact relative to the scale of the platform may not create an alert. In a single-tenant instance, however, the same bugs or scaling issues can quickly impact a higher percentage of the overall users of the instance, escalating the issue's importance. Applying our service-level monitoring to single-tenant GitLab instances has benefited GitLab users who had encountered bugs that were overlooked in the volume of GitLab.com usage. When we identify issues in a Dedicated instance, we resolve them within the product.\n\n## High availability for all components\nConsidering the hybrid environment and the level of service that we want to offer to our customers, we have made some minor changes from the [standard reference architecture](https://docs.gitlab.com/ee/administration/reference_architectures/).\n\nOne such change is introducing high availability for all components. For the lower size (i.e., up to 2,000 users), our architecture ships by default with all the components in full redundant mode. Components like RDS and Elasticache will have a replica in a different Availability Zone. This is referred to as the primary region and we have to define how it will look in the [Geo replicas](https://docs.gitlab.com/ee/administration/geo/setup/database.html).\n\n## Only on Dedicated\nIn addition to the other changes we made, we also built some features that are only used for GitLab Dedicated:\n- Bring your own key - customers can provide and manage the encryption keys used to encrypt AWS resources such as storage, allowing a customer to revoke access should that ever become necessary. This is not something that can be offered in a multi-tenant system like GitLab.com.\n- Switchboard - as mentioned above, Switchboard was purpose-built for Dedicated. It is a multi-tenant Ruby on Rails application, accessible by GitLab Dedicated customer administrators and GitLab Dedicated team members. Using this interface, customers can change the available application runtime settings, access provided graphs, add additional products, and more. The main Switchboard instance serves as a single source of truth for global configuration and status across multiple cloud providers and regions.\n- PrivateLink networking - allows traffic between tenant AWS accounts and customer accounts without exposing data to the internet. \n- Other network features - including traffic filtering and private hosted zones.\n\nDedicated has been an exciting project and a great learning experience for our team. We were able to apply the knowledge accumulated in building GitLab.com to deliver an important new product for our customers in a very efficient way. You can learn more about GitLab Dedicated by visiting our [Dedicated page](https://about.gitlab.com/dedicated/) or contacting a GitLab sales representative.\n\n_Check out the [first installment in our \"Building GitLab with GitLab\" series](https://about.gitlab.com/blog/building-gitlab-with-gitlab-api-fuzzing-workflow/), which takes you behind the scenes of the development of our web API fuzz testing._\n",[1084,496,9,719],"AWS",{"slug":1086,"featured":6,"template":698},"building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated","content:en-us:blog:building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated.yml","Building Gitlab With Gitlabcom How Gitlab Inspired Dedicated","en-us/blog/building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated.yml","en-us/blog/building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated",{"_path":1092,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1093,"content":1099,"config":1105,"_id":1107,"_type":14,"title":1108,"_source":16,"_file":1109,"_stem":1110,"_extension":19},"/en-us/blog/can-your-ci-cd-environment-support-ai-powered-devsecops",{"title":1094,"description":1095,"ogTitle":1094,"ogDescription":1095,"noIndex":6,"ogImage":1096,"ogUrl":1097,"ogSiteName":686,"ogType":687,"canonicalUrls":1097,"schema":1098},"Can your CI/CD environment support AI-powered DevSecOps? ","Unlock the value of AI-powered software development with a DevSecOps platform capable of supporting CI/CD hyperscale.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683522/Blog/Hero%20Images/AdobeStock_659839979.jpg","https://about.gitlab.com/blog/can-your-ci-cd-environment-support-ai-powered-devsecops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Can your CI/CD environment support AI-powered DevSecOps? \",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Darren Eastman\"}],\n        \"datePublished\": \"2024-01-03\",\n      }",{"title":1094,"description":1095,"authors":1100,"heroImage":1096,"date":1102,"body":1103,"category":781,"tags":1104},[1101],"Darren Eastman","2024-01-03","Our customers are experiencing a significant increase in the efficiency and pace of software development with [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our suite of AI capabilities powering your workflow. This will likely correspond to a rise in the two [DORA metrics](https://about.gitlab.com/solutions/value-stream-management/dora/) that measure velocity: deployment frequency and lead time for changes. However, what may not be as obvious is that the age of AI-powered software development has also ushered in a new era of large-scale computing for CI/CD jobs. Organizations will need to learn how to support this CI/CD hyperscale.\n\n## What is CI/CD hyperscale?\n\nAs a quick recap, a [CI/CD](https://about.gitlab.com/topics/ci-cd/) job is a unit of work that is executed on a host computing system each time a developer pushes a code change to a project repository. This core guiding principle has accelerated value creation by software development teams over the past few years. Instead of focusing on the ceremonies of legacy project management, today’s leading software development teams deliver value by adding small increments to a software product regularly – weekly, daily, and even hourly.\n\nThe CI/CD engine supports this modern pattern of software product development by enabling development teams to define automation to continuously build, test, and integrate any new software change. Some of our larger customers who have transformed their software development practices have already attained what we at GitLab have labeled as CI/CD hyperscale. That is, they are typically running 3 million or more CI/CD jobs per month.\n\n## How to support AI-fueled CI/CD growth\n\nWith the advent of AI-powered DevSecOps, we hypothesize that, starting in 2024, organizations will see a 2x increase per year in the number of CI/CD jobs run by development teams leveraging AI-assisted features across the software development lifecycle. Starting with 3 million jobs per month as the baseline and assuming a 2% growth rate per month, the chart below illustrates the potential impact in the growth of CI/CD jobs monthly due to efficiency gains with AI-powered DevSecOps.\n\n![cicd hyperscale chart](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683548/Blog/Content%20Images/image1.png)\n\nSo, what steps can you take to ensure your organization is positioned for success in this hyper-competitive new age of AI-powered DevSecOps? \n\nHere are a few pointers to get you started:\n\n- Analyze whether you have enabled your development teams – the creators of value – with the flexibility to adopt modern patterns in software product development. \n- Inventory the tools you use to support creative work, including project and task management.\n- Inventory the tools you use for software development and DevOps. Are you using multiple types of CI systems across your environment? If so, the next step is to gain a deeper understanding of why that is. \n- Create a plan to migrate all software development teams from multiple point solutions to one DevSecOps platform. \n\nYour software development teams may have built up extensive tooling using various CI systems and point solutions and may question the return on investment of a potentially time-consuming consolidation and migration effort. However, based on our internal data, customers adopting GitLab [realize payback in less than six months](https://about.gitlab.com/blog/why-the-market-is-moving-to-a-platform-approach-to-devsecops/).  \n\nIf you have already adopted the GitLab AI-powered DevSecOps Platform and are consolidating your platform engineering and software development processes, then you are well on your way to unlocking the value of AI-powered software development and having a solution capable of supporting CI/CD hyperscale. \n\nAs the pioneer of the integrated DevSecOps platform, we have been at the forefront of supporting CI/CD hyperscale for customers running CI/CD workloads on the fully managed GitLab SaaS CI/CD build environment or their own self-managed build infrastructure. That focused investment over the past decade has resulted in the development of the most scalable and flexible CI/CD engine – the core of the GitLab DevSecOps Platform. Look no further than our milestone of [more than 1 billion pipelines run on GitLab's SaaS-based DevSecOps Platform](https://about.gitlab.com/blog/one-billion-pipelines-cicd/). \n\nSo with GitLab CI and GitLab Runner, the ultimate CI/CD execution engine, the GitLab DevSecOps Platform is a solution that provides the foundation to continuously improve and transform your value creation processes while supporting the scale required to meet the competitive demands of the new age of AI.\n\n## Learn how to achieve CI/CD hyperscale\n\nIf you are new to GitLab and are interested in learning how we can help you transform your software development processes, [contact our sales team](https://about.gitlab.com/sales/) to help you with a custom demo and get you going on your adoption of AI-powered DevSecOps.\n",[109,9,717],{"slug":1106,"featured":6,"template":698},"can-your-ci-cd-environment-support-ai-powered-devsecops","content:en-us:blog:can-your-ci-cd-environment-support-ai-powered-devsecops.yml","Can Your Ci Cd Environment Support Ai Powered Devsecops","en-us/blog/can-your-ci-cd-environment-support-ai-powered-devsecops.yml","en-us/blog/can-your-ci-cd-environment-support-ai-powered-devsecops",{"_path":1112,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1113,"content":1119,"config":1125,"_id":1127,"_type":14,"title":1128,"_source":16,"_file":1129,"_stem":1130,"_extension":19},"/en-us/blog/ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch",{"title":1114,"description":1115,"ogTitle":1114,"ogDescription":1115,"noIndex":6,"ogImage":1116,"ogUrl":1117,"ogSiteName":686,"ogType":687,"canonicalUrls":1117,"schema":1118},"CI/CD Catalog goes GA: No more building pipelines from scratch","The CI/CD Catalog becomes generally available in GitLab 17.0. Get to know the capabilities for discovering and sharing pipeline building blocks to help standardize and scale pipelines.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098794/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%289%29_DoeBNJVrhv9FpF3WCsHNc_1750098793762.png","https://about.gitlab.com/blog/ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"CI/CD Catalog goes GA: No more building pipelines from scratch\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Dov Hershkovitch\"}],\n        \"datePublished\": \"2024-05-08\",\n      }",{"title":1114,"description":1115,"authors":1120,"heroImage":1116,"date":1122,"body":1123,"category":848,"tags":1124},[1121],"Dov Hershkovitch","2024-05-08","GitLab's [CI/CD Catalog](https://docs.gitlab.com/ee/ci/components/#cicd-catalog) becomes generally available in 17.0 (May 16, 2024), enabling all GitLab users to discover, reuse, and contribute CI/CD components easily. The CI/CD Catalog boosts collaboration and efficiency when creating pipeline configurations by allowing access to a treasure trove of pre-built components, ready to seamlessly integrate into DevSecOps workflows. Enterprises can use the CI/CD Catalog's centralized platform to standardize workflows across the whole organization.\n\nWith the CI/CD Catalog, GitLab is introducing several key capabilities that are also generally available.\n\n> Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Watch today!](https://about.gitlab.com/seventeen/)\n\n## Components and inputs\nThe [CI/CD Catalog](https://about.gitlab.com/blog/introducing-the-gitlab-ci-cd-catalog-beta/) draws its strength from two fundamental features: components and inputs. These capabilities form the backbone of the catalog, enabling developers and DevSecOps teams to streamline their pipeline development. Let’s dive into each of these features:\n\n### Components\n\n#### What are components?\nComponents are reusable, single-purpose building blocks that abstract away the complexity of pipeline configuration. Think of them as Lego pieces for your CI/CD workflows. By using components, you can assemble pipelines more efficiently without starting from scratch each time.\n\n#### Types of components\n- Template-type components: These components resemble CI templates and come with predefined input definitions. They are organized within a specific directory structure, which you can easily plug into your pipelines.\n- CI Steps (upcoming): This new type of component, which is available as an [experimental feature](https://docs.gitlab.com/ee/ci/steps/), will become a first-class object in the CI/CD Catalog, so stay tuned for this exciting addition.\n\n### Inputs\n\n#### What is Inputs Interpolation?\n\nInputs Interpolation is a powerful feature that allows you to define input parameters for includable configuration files. By using the [spec: inputs keyword](https://docs.gitlab.com/ee/ci/yaml/#specinputs) within your component configuration, you can dynamically replace almost any keywords within components with parameters. This flexibility extends to adjusting stages, scripts, or job names, supporting various data types making the component fully flexible to your needs.\n\n##### Scoped and effective\nImportantly, inputs are scoped exclusively to the included configuration. This prevents unintended effects on the rest of your pipeline. With Inputs Interpolation, you can declare and enforce constraints seamlessly, ensuring smooth integration of components.\n\nWhether you’re a seasoned DevOps pro or just starting out, the CI/CD Catalog, components, and Inputs Interpolation will transform your pipeline development experience.\n\n## How to access CI/CD Catalog components\nThe CI/CD Catalog is a powerful resource for developers and DevOps teams. It allows you to share and discover pre-built components, streamlining your pipeline development. Here’s how it works:\n\n1. Components are standalone building blocks that simplify pipeline configuration. You can create custom components tailored to your needs. But how do you make them available to others? That’s where the CI/CD Catalog comes in.\n\n2. How to publish to the CI/CD Catalog\n    - To share your components with the community, follow these steps:\n      - Use a simple CI job to publish your component and make it discoverable in the CI/CD Catalog.\n      - Whether it’s a reusable script, a deployment template, or any other pipeline element, the CI/CD Catalog is the perfect place to contribute.\nComponents released to the CI/CD Catalog should be tagged with a [semantic version](https://docs.gitlab.com/ee/ci/components/#semantic-versioning) using three digits.\n    - By sharing your components, you contribute to a growing library of resources that benefit the entire community.\n3. Catalog index page\n    - The main page of the CI/CD Catalog (also known as the index page) provides an overview of available projects with published components. Anyone can access the catalog and search for a component that suits their needs.\n    - The index page features two tabs:\n      - All: Displays all component projects that have been published and visible to you.\n      - Your groups: Shows components published within a namespace you’re part of.\n\n![CI/CD Catalog](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098805/Blog/Content%20Images/Blog/Content%20Images/catalog_index_aHR0cHM6_1750098804807.png)\n\n4.  Catalog details page\n\n- Upon clicking on one of the projects in the CI/CD Catalog, you will be redirected to the details page where you can view the available components in that project. \n    - Note that there could be multiple components in a single project.\n\n- The details page features two tabs:\n\u003Ccenter>\u003Ci>Readme: Displays the readme.md of the project that was previously configured by the user.\u003C/i>\u003C/center>\n\n![readme tab](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098805/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098804808.png)\n\n\u003Ccenter>\u003Ci>Components: Displays the detailed information for each component such as inputs table syntax to use and more. This information is generated and displayed automatically to help keep it up to date.\u003C/i>\u003C/center>\n\n![components tab](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098805/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098804809.png)\n\n## Using a component\n\nTo use a component from the CI/CD Catalog, simply copy the suggested snippet to your pipeline configuration. For example: \n\n```yaml\n\ninclude: \n  - component:   gitlab.com/google-gitlab-components/cloud-run/deploy-cloud-run@0.1.0\n\n```\n\nNote that the snippet contains the fully qualified domain name of the component, so if you moved or clone the component to a different location, you should make sure the FQDN is accurate. You can use the $CI_SERVER_FQDN variable instead of hardcoding the FQDN in your pipeline configuration.\n\nA component can be referenced using the following:\n\n- a commit SHA, for example, e3262fdd0914fa823210cdb79a8c421e2cef79d. We highly recommend using this with $CI_COMMIT_SHA variable in your `.gitlab.ci.yml` file to test a component before publishing it to the CI/CD Catalog.\n- a branch name, for example, main\n- a tag, for example 1.0.0\n- shorthand abbreviation 1.0, which will provide you the latest patched 1.0.x version or 1, which will provide you the latest 1.x.x minor version. This is why it is recommended to use the best practices of semantic versioning and always reference a specific version (minor, major, or a specific patch).\n- ~latest, which always points to the latest semantic version published in the CI/CD Catalog. Use ~latest only if you want to use the absolute latest version at all times, which could include breaking changes., so please use it with caution.\n\n## Understanding the CI/CD Catalog across GitLab deployments\nThe CI/CD Catalog and components offer different flavors to cater to various needs and use cases.\n\n### Private and public components\n\n#### Public components\n\n- Public components are hosted in public repositories and are accessible to everyone.\n- When a public component is published from GitLab.com to the main catalog, it becomes discoverable and available for consumption by all users.\n- We encourage users to contribute their best components to the public catalog, helping us build a thriving community.\n\n#### Private components\n\n- Private components are hosted in private repositories.\n- Visibility based on permissions: Users who access the catalog can also see and search for private components if they have permission to view the repository where the component is hosted.\n    - Private catalog option: In GitLab.com, organizations can publish private components to the main catalog in GitLab.com, thereby creating a “private catalog” with content accessible only to authorized users. \n\n### GitLab.com vs. Self-managed\n- The “public” catalog in GitLab.com: The main catalog is the one that is hosted on GitLab.com and can be accessible to anyone by going to [gitlab.com/explore/catalog](http://gitlab.com/explore/catalog). The CI/CD Catalog is:\n    - Open access: The catalog hosted on GitLab.com is available for anyone to view.\n    - Contribute and grow: By sharing components, users around the world contribute to a growing library of resources that benefits the entire community.\n\n- Self-managed customers: The CI/CD Catalog is also available for self-managed customers however it has several differences: \n    - Empty catalog: For self-managed customers, the catalog initially appears empty since it doesn't contain any available components.\n    - Organizational catalog: Each organization is responsible for its own catalog, where it can create and maintain its own library of components within this flavor.\n    - Using a component from GitLab.com: If you want to use a component from the main catalog in GitLab.com, clone the project locally and publish it to your organizational catalog. Keep in mind that upstream updates will require mirroring to receive the latest changes. You can learn more about how to do that in our [CI/CD Components documentation](https://docs.gitlab.com/ee/ci/components/#use-a-gitlabcom-component-in-a-self-managed-instance).\n\n## What’s next?\n\nThe CI/CD Catalog is only the first step in revolutionizing the way you build and display your available pipelines. Here is a glimpse of what we plan to offer to our users in the upcoming milestones.\n\n### CI Steps\n\nSteps are reusable and composable pieces of a job that can be referenced in your pipeline configuration. Each step defines structured inputs and outputs that can be consumed by other steps. Steps can come from local files, GitLab.com repositories, or any other Git source.\n\nIn GitLab, we think of steps as another type of component. We are going to make sure CI Steps will become a first-class object in the CI/CD Catalog, where users can publish, unpublish, search, and consume steps in the same way as they are using components today.\n\n### Securing your catalog workflows\n\nWe aim to empower central administrators to manage component creation, usage, and publication within their organizational catalog. We are committed to ensuring the publishing process seamlessly integrates with the organization's standards and existing workflow. We want to enable the platform administrators with the capabilities to secure and govern the CI/CD Catalog and component workflows. More information can be found in [this epic](https://gitlab.com/groups/gitlab-org/-/epics/12713).\n\n### Analytics\n\nOur goal is to empower users with seamless control over component management across pipelines, ensuring optimal version control and project alignment. This addresses the challenge of users currently lacking visibility into component usage across various project pipelines. Our objective is to provide users with the capability to swiftly identify outdated versions and take prompt corrective actions as needed. This enhancement will foster an environment where users can efficiently manage and update components, promoting both version control precision and project alignment. Read more in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/393326).\n\n## Get started with the CI/CD Catalog\n\nThe introduction of the CI/CD Catalog revolutionizes pipeline development by offering a vast array of pre-built components. Users don't have to start building pipelines from scratch because the CI/CD Catalog provides an access point to search components and pipeline configurations. The CI/CD Catalog's availability makes accessing and sharing components effortless, fostering collaboration and community growth. Whether utilizing public or private repositories, users can leverage these resources to enhance their pipeline development experience. Moreover, while GitLab.com users benefit from an open-access catalog, self-managed customers can establish organizational catalogs tailored to their needs.\n\n> [Get to know the CI/CD Catalog](https://about.gitlab.com/free-trial/devsecops/) with a free trial of GitLab Ultimate.\n\n> Learn more about the CI/CD Catalog and components:\n> \n> - [A CI/CD component builder's journey](https://about.gitlab.com/blog/a-ci-component-builders-journey/)\n>\n> - [FAQ: GitLab CI/CD Catalog](https://about.gitlab.com/blog/faq-gitlab-ci-cd-catalog/)\n>\n> - [Documentation: CI/CD components and CI/CD Catalog](https://docs.gitlab.com/ee/ci/components/)\n> \n> - [Introducing CI/CD components and how to use them in GitLab](https://about.gitlab.com/blog/introducing-ci-components/)\n> \n",[109,9,496,719],{"slug":1126,"featured":91,"template":698},"ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch","content:en-us:blog:ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch.yml","Ci Cd Catalog Goes Ga No More Building Pipelines From Scratch","en-us/blog/ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch.yml","en-us/blog/ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch",{"_path":1132,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1133,"content":1138,"config":1143,"_id":1145,"_type":14,"title":1146,"_source":16,"_file":1147,"_stem":1148,"_extension":19},"/en-us/blog/code-suggestions-for-all-during-beta",{"title":1134,"description":1135,"ogTitle":1134,"ogDescription":1135,"noIndex":6,"ogImage":839,"ogUrl":1136,"ogSiteName":686,"ogType":687,"canonicalUrls":1136,"schema":1137},"Code Suggestions available to all GitLab tiers while in Beta","All users can acess Code Suggestions AI-assisted feature while it is in Beta.","https://about.gitlab.com/blog/code-suggestions-for-all-during-beta","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Code Suggestions available to all GitLab tiers while in Beta\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Neha Khalwadekar\"}],\n        \"datePublished\": \"2023-05-16\",\n      }",{"title":1134,"description":1135,"authors":1139,"heroImage":839,"date":1140,"body":1141,"category":781,"tags":1142},[844],"2023-05-16","\n\n\u003Ci>This blog is the latest post in an ongoing series about GitLab’s journey to \u003Ca href=\"/blog/ai-ml-in-devsecops-series/\">build and integrate AI/ML into our DevSecOps platform\u003C/a>. The first blog post can be found \u003Ca href=\"/blog/what-the-ml-ai/\">here\u003C/a>. Throughout the series, we’ll feature blogs from our product, engineering, and UX teams to showcase how we’re infusing AI/ML into GitLab.\u003C/i>\n\nCode Suggestions is now available on GitLab.com for all users for free while the feature is in Beta. Teams can boost efficiency with the help of generative AI that suggests code while you're developing. We've extended language support from our initial six languages to now include 13 languages: C/C++, C#, Go, Java, JavaScript, Python, PHP, Ruby, Rust, Scala, Kotlin, and TypeScript. \n\nWe are making improvements to the Code Suggestions underlying AI model weekly to improve the quality of suggestions. Please remember that AI is non-deterministic, so you may not get the same suggestion week to week.\n\n## Privacy first\nCode Suggestions is built with privacy as a critical foundation. It keeps your proprietary source code secure within GitLab's enterprise cloud infrastructure, and this code isn't used as training data. Source code inference against the Code Suggestions model is not used to re-train the model. Learn about [data usage when using Code Suggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#code-suggestions-data-usage). \n\n## IDE support\nCode Suggestions is available in VS Code via the [GitLab Workflow extension](https://docs.gitlab.com/ee/user/project/repository/vscode.html#gitlab-workflow-extension-for-vs-code). We will soon support the GitLab WebIDE with GitLab 16.0. We are also working on adding [additional IDE support](https://gitlab.com/groups/gitlab-org/-/epics/10542) based on customer feedback, including JetBrains IntelliJ-based IDEs and Visual Studio support for code suggestions. We are also working to improve the user experience for how suggestions are presented and accepted within the IDEs to give developers more control over how the feature works. Additionally we're working to make it easier to setup Code Suggestions the first time and authenticate with GitLab.com \n\n## Self-managed support\nWe are also working to bring Code Suggestions to self-managed instances [via a secure connection to GitLab.com](https://gitlab.com/groups/gitlab-org/-/epics/10528). If you have unique requirements for your self-managed instances, we welcome you to express your interest in our [self-managed support issue](https://gitlab.com/gitlab-org/gitlab/-/issues/409183). Commenting on that issue will give you notifications as we post updates. \n\n## Enable Code Suggestions\nOur documentation details how to [enable Code Suggestions in VS Code](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-in-vs-code). Below is a quickstart video walkthrough:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n\u003Ciframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/WnxBYxN2-p4\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen>\u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Beta feature\nThis feature is in [Beta](https://docs.gitlab.com/ee/policy/experiment-beta-support.html#beta). Code Suggestions uses generative AI to suggest code while you're developing. Due to high demand, this feature will have unscheduled downtime and code suggestions in VS Code may be delayed. Code Suggestions may produce [low-quality or incomplete suggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#model-accuracy-and-quality). We look forward to hearing your feedback. Beta users should read about the [known limitations](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#known-limitations). \n\nWe would love to hear about your experience and report issues in the [feedback issues](https://gitlab.com/gitlab-org/gitlab/-/issues/405152). \n\nCode Suggestions is just one of the ways we’re infusing GitLab with AI/ML capabilities to help GitLab users become more efficient and effective at their jobs. We are [looking across the software development lifecycle](/blog/what-the-ml-ai/) for painful and time-consuming tasks that are ideal for AI-assisted features. We'll continue to share these demos throughout this blog series.\n\nInterested in using these AI-powered features? [Join our waitlist](https://forms.gle/9eeUkPJauKsbLaoz5) and share your ideas.\n\nContinue reading our \"[AI/ML in DevSecOps](https://about.gitlab.com/blog/ai-ml-in-devsecops-series/)\" series.\n\n_Disclaimer: This blog contains information about upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[9,848,719,717],{"slug":1144,"featured":6,"template":698},"code-suggestions-for-all-during-beta","content:en-us:blog:code-suggestions-for-all-during-beta.yml","Code Suggestions For All During Beta","en-us/blog/code-suggestions-for-all-during-beta.yml","en-us/blog/code-suggestions-for-all-during-beta",{"_path":1150,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1151,"content":1156,"config":1161,"_id":1163,"_type":14,"title":1164,"_source":16,"_file":1165,"_stem":1166,"_extension":19},"/en-us/blog/code-suggestions-improves-developer-productivity",{"title":1152,"description":1153,"ogTitle":1152,"ogDescription":1153,"noIndex":6,"ogImage":839,"ogUrl":1154,"ogSiteName":686,"ogType":687,"canonicalUrls":1154,"schema":1155},"How Code Suggestions can supercharge developers' daily productivity","Learn how you can use GitLab Code Suggestions to accelerate your development.","https://about.gitlab.com/blog/code-suggestions-improves-developer-productivity","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How Code Suggestions can supercharge developers' daily productivity\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Neha Khalwadekar\"}],\n        \"datePublished\": \"2023-05-25\",\n      }",{"title":1152,"description":1153,"authors":1157,"heroImage":839,"date":1158,"body":1159,"category":781,"tags":1160},[844],"2023-05-25","\n\n\u003Ci>This blog is the latest post in an ongoing series about GitLab’s journey to \u003Ca href=\"/blog/ai-ml-in-devsecops-series/\">build and integrate AI/ML into our DevSecOps platform\u003C/a>. The first blog post can be found \u003Ca href=\"/blog/what-the-ml-ai/\">here\u003C/a>. Throughout the series, we’ll feature blogs from our product, engineering, and UX teams to showcase how we’re infusing AI/ML into GitLab.\u003C/i>\n\nIn the fast-paced world of software development, time is a precious resource. Developers constantly strive for ways to improve the productivity and efficiency of their workflows. Enter Code Suggestions, a large language model (LLM)-based technology that can transform the everyday developer experience. Let’s delve into the novel use cases of Code Suggestions, including: \n\n* simplifying operations\n* assisting new developers in language explorations\n* eliminating the need for frequent web searches by experienced developers\n\nAll of these are examples of how Code Suggestions can accelerate the daily developer experience. Let’s explore some specific examples of these use cases.\n\n## Import packages\nWith Code Suggestions, developers can quickly complete mundane tasks like importing Python packages. \n![Example](https://about.gitlab.com/images/blogimages/2023-05-25-Blog-code-suggestions-improves-developer-productivity/python_packages.gif)\n\n\n## Complete functions\nCode Suggestions can help developers complete functions and use those functions to write code. In the example below, we are defining the first and last name and then defining a full name. Now we can take this a step forward and use those defined functions in a user form. \n![Example](https://about.gitlab.com/images/blogimages/2023-05-25-Blog-code-suggestions-improves-developer-productivity/sample_functions.gif)\n\n\n## Fill in boilerplate\nDevelopers can use Code Suggestions to recommend boilerplate code such as connecting to a mySQL database.\n![Example](https://about.gitlab.com/images/blogimages/2023-05-25-Blog-code-suggestions-improves-developer-productivity/mysql-boiler.gif)\n\n\n## Building data frames\nData manipulation is a fundamental task for developers working with structured data. Code Suggestions can simplify the process of offering intelligent recommendations for DataFrame operations. Code Suggestions can assist in saving developers the time and effort of searching through documentation or experimenting with trial and error.\n![Example](https://about.gitlab.com/images/blogimages/2023-05-25-Blog-code-suggestions-improves-developer-productivity/dataframe.gif)\n\n\n## Generate unit tests\nWith Code Suggestions, developers can quickly write unit tests for the supported programming languages.\n![Example](https://about.gitlab.com/images/blogimages/2023-05-25-Blog-code-suggestions-improves-developer-productivity/unit-test.gif)\n\n\n## Try Code Suggestions today\nCode Suggestions is now available for free on GitLab.com for all users while the feature is in Beta. Teams can boost efficiency with the help of generative AI that suggests code while they're developing. We are improving the underlying AI model weekly to improve the [quality of suggestions](https://gitlab.com/groups/gitlab-org/-/epics/10562). Please remember that AI is non-deterministic, so you may not get the same suggestion from week to week. Also remember that any time you are using AI-generated code you should be automatically analyzing it with [code quality](https://docs.gitlab.com/ee/ci/testing/code_quality.html) and [security scanning](https://docs.gitlab.com/ee/user/application_security/), both of which are available natively in the GitLab platform. \n\nWe’ve extended [language support](https://gitlab.com/groups/gitlab-org/-/epics/10561) from our initial six languages to now include 13 languages: C/C++, C#, Go, Java, JavaScript, Python, PHP, Ruby, Rust, Scala, Kotlin, and TypeScript.\n\nRead more about these [improvements and what’s next.](https://about.gitlab.com/blog/code-suggestions-for-all-during-beta/)\n\nInterested in using these AI-powered features? [Join our waitlist](https://forms.gle/9eeUkPJauKsbLaoz5) and share your ideas.\n\nContinue reading our \"[AI/ML in DevSecOps](https://about.gitlab.com/blog/ai-ml-in-devsecops-series/)\" series.\n\n_Disclaimer: This blog contains information about upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[9,848,719,717],{"slug":1162,"featured":6,"template":698},"code-suggestions-improves-developer-productivity","content:en-us:blog:code-suggestions-improves-developer-productivity.yml","Code Suggestions Improves Developer Productivity","en-us/blog/code-suggestions-improves-developer-productivity.yml","en-us/blog/code-suggestions-improves-developer-productivity",{"_path":1168,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1169,"content":1174,"config":1179,"_id":1181,"_type":14,"title":1182,"_source":16,"_file":1183,"_stem":1184,"_extension":19},"/en-us/blog/comply-with-nist-secure-supply-chain-framework-with-gitlab",{"title":1170,"description":1171,"ogTitle":1170,"ogDescription":1171,"noIndex":6,"ogImage":794,"ogUrl":1172,"ogSiteName":686,"ogType":687,"canonicalUrls":1172,"schema":1173},"Comply with NIST's secure software supply chain framework with GitLab","The U.S. government's Secure Software Development Framework has four key practices. GitLab's DevOps platform has features to address them all.","https://about.gitlab.com/blog/comply-with-nist-secure-supply-chain-framework-with-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Comply with NIST's secure software supply chain framework with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sandra Gittlen\"}],\n        \"datePublished\": \"2022-03-29\",\n      }",{"title":1170,"description":1171,"authors":1175,"heroImage":794,"date":1176,"body":1177,"category":694,"tags":1178},[799],"2022-03-29","\nThe U.S. government, in March, released an update to its framework to secure agencies’ software supply chains, which are under [increasing risk of attack](https://www.whitehouse.gov/briefing-room/statements-releases/2022/03/21/statement-by-president-biden-on-our-nations-cybersecurity/). The National Institute of Standards and Technology (NIST) unveiled the Secure Software Development Framework (SSDF) 1.1, which calls for tighter controls throughout the software development lifecycle and describes a set of best practices for organizations – and their third-party suppliers – to follow.\n\nThe [SSDF](https://csrc.nist.gov/News/2022/nist-publishes-sp-800-218-ssdf-v11) focuses on how organizations can protect software supply chains, regardless of technology, platform, programming language, or operating environment, in large part by introducing security early in the DevOps process. There are four key practices:\n\n- prepare the organization\n\n- protect software (all components of the software should be safe from tampering and unauthorized access)\n\n- produce well-secured software (with minimal security vulnerabilities in its releases)\n\n- respond to vulnerabilities\n\n“The goal of the SSDF, in my opinion, is to bring all agencies and their suppliers to the same place in terms of secure software development,” says Joel Krooswyk, senior manager of Solutions Architecture at GitLab. “The framework gets everyone on the same page and speaking the same language, which will inevitably help them to be more effective against whatever threats may come.”\n\nWhile some agencies, such as the Department of Defense and Central Intelligence Agency, might be more sophisticated in the security and compliance of their software supply chains, other public sector organizations are less advanced, using a raft of ad-hoc legacy applications to manually handle vulnerabilities.\n\nThe SSDF undoubtedly will drive all government agencies to direct resources – human and technological – toward [automating supply chain security](/blog/gitlab-supply-chain-security/). To ensure that they meet the measure of the framework without overburdening their teams and budgets, organizations should consider deploying GitLab, a single DevOps platform that has security built in early in the development lifecycle, end-to-end, and with maximum visibility. \n\nHere’s how GitLab addresses the specific practices within the SSDF:\n\n**1. Prepare the organization**\n\nGitLab helps organizations ensure that their people, processes, and technology are prepared to perform security software development, in line with SSDF best practices.\n\nThe GitLab DevOps platform features:\n\n- Strong [policy management](https://docs.gitlab.com/ee/administration/compliance.html) and role-based permissions models with LDAP, single sign-on, and multifactor authentication support\n\n- [Sophisticated security dashboards](https://docs.gitlab.com/ee/user/application_security/security_dashboard/) with severity and trends to provide all stakeholders visibility and observability into the software development lifecycle \n\n- Scaled agile process support, which is enabled through epics and issues and other documentation, making for a completely auditable environment\n\n- Simplified implementation of a zero-trust security framework with the DevOps platform\n\n**2. Protect the software**\n\nThe SSDF guides organizations to protect all components of their software from tampering and unauthorized access.\n\nGitLab helps organizations accomplish this through the use of:\n\n- [source code management](https://about.gitlab.com/solutions/source-code-management/)\n\n- commit signatures\n\n- code reviews\n\n- [Hardened containers](/press/releases/2020-07-01-gitlab-announces-hardened-container-image-in-support-of-the-us-department-of-defense-enterprise-devsecops-initiative/)\n\n- role-based, read-only controls\n\n- [Merge-request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) \n\n- [Software Bill of Materials (SBOM)](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#cyclonedx-software-bill-of-materials) data per release\n\n- security scanning in [offline environments](https://docs.gitlab.com/ee/user/application_security/offline_deployments/)\n\n**3. Produce well-secured software**\n\nAccording to the SSDF, organizations should produce well-secured software with minimal security vulnerabilities in its releases.\n\nThe GitLab DevOps platform is purpose-built for this best practice and includes:\n\n- credential management\n\n- code reviews and approvals\n\n- centralized mitigation with vulnerability reports\n\n- [security scanning](https://docs.gitlab.com/ee/user/application_security/) (DAST, SAST, fuzz testing, secret detection, and more) that is integrated into the developer workflow\n\n- [continuous compliance](/solutions/compliance/) enforcement capabilities that enable organizations to tailor their pipeline reviews and security scans to all their applicable compliance mandates\n\n- the ability to find and fix vulnerabilities early on in development without building complex integrations\n\n**4. Respond to vulnerabilities**\n\nThe SSDF wants organizations to be able to identify residual vulnerabilities in their software releases and respond appropriately to address those vulnerabilities and prevent similar ones from occurring in the future.\n\nGitLab enables organizations to find and fix vulnerabilities early in the development process. The GitLab DevOps platform also features:\n\n- automatic updates for the Common Vulnerabilities and Exposures (CVE) database\n\n- the ability to contribute/disclose vulnerabilities directly via GitLab\n\n- [Auto DevOps](https://docs.gitlab.com/ee/topics/autodevops/) best practice scanning\n\n- status, severity, and related activity exposed on the [Vulnerability Report](https://docs.gitlab.com/ee/user/application_security/vulnerability_report/) page\n\n- integrated learning tools to learn about found vulnerabilities in real-time\n\n- on-demand scanning to look for new vulnerabilities in existing code\n\nUsing GitLab's DevOps platform, government agencies, and their suppliers, can apply the best practices set forth in the SSDF and ensure the software supply chain meets the requirements of other mandates through [continuous compliance](/solutions/compliance/).\n\n[Try GitLab Ultimate for free](/solutions/public-sector/)\n",[9,496,694,186],{"slug":1180,"featured":6,"template":698},"comply-with-nist-secure-supply-chain-framework-with-gitlab","content:en-us:blog:comply-with-nist-secure-supply-chain-framework-with-gitlab.yml","Comply With Nist Secure Supply Chain Framework With Gitlab","en-us/blog/comply-with-nist-secure-supply-chain-framework-with-gitlab.yml","en-us/blog/comply-with-nist-secure-supply-chain-framework-with-gitlab",{"_path":1186,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1187,"content":1192,"config":1199,"_id":1201,"_type":14,"title":1202,"_source":16,"_file":1203,"_stem":1204,"_extension":19},"/en-us/blog/dast-release-first-gitlab-active-check",{"title":1188,"description":1189,"ogTitle":1188,"ogDescription":1189,"noIndex":6,"ogImage":773,"ogUrl":1190,"ogSiteName":686,"ogType":687,"canonicalUrls":1190,"schema":1191},"Introducing GitLab browser-based active checks in DAST","As of GitLab 16.4, or DAST 4.0.9, browser-based DAST active scans will search for path traversal vulnerabilities using the GitLab check 22.1 instead of the ZAP alert 6.","https://about.gitlab.com/blog/dast-release-first-gitlab-active-check","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Introducing GitLab browser-based active checks in DAST\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Cameron Swords\"}],\n        \"datePublished\": \"2023-10-10\",\n      }",{"title":1188,"description":1189,"authors":1193,"heroImage":773,"date":1195,"body":1196,"category":694,"tags":1197},[1194],"Cameron Swords","2023-10-10","GitLab's [DAST](/direction/secure/dynamic-analysis/dast/) and [Vulnerability\nResearch](/handbook/engineering/development/sec/secure/vulnerability-research/)\nteams released the first GitLab active check in browser-based dynamic\napplication security testing. This continues our work to integrate passive\nchecks into browser-based DAST. As of GitLab 16.4, or DAST 4.0.9,\nbrowser-based DAST active scans will search for path traversal\nvulnerabilities using the GitLab check\n[22.1](https://docs.gitlab.com/ee/user/application_security/dast/checks/22.1.html)\ninstead of the ZAP alert [6](https://www.zaproxy.org/docs/alerts/6/).\n\n\nReplacing ZAP alerts with GitLab active checks enables developers and\nsecurity teams to detect vulnerabilities in modern-day web applications more\neffectively. Going forward, we anticipate replacing more ZAP alerts with\nGitLab active checks. If you are interested in using the browser-based DAST\nanalyzer, please see: [How to configure a browser-based DAST scan\ndocumentation](https://docs.gitlab.com/ee/user/application_security/dast/browser_based.html).\n\n\nBelow is an explanation of how active checks work, different types of\nattacks, and worked examples of browser-based attacks.\n\n\n## How to use GitLab active checks\n\nCustomers who run active scans (full scans) will automatically run GitLab\nactive checks as they are tested and released by the DAST team. Each\ncorresponding ZAP alert will be turned off at this time.\n\n\nCustomers can opt out of these changes, disabling the GitLab active checks\nand re-enabling the ZAP alerts by adding the CI/CD variable\n`DAST_FF_BROWSER_BASED_ACTIVE_ATTACK: \"false\"`.\n\n\n## What is an active check?\n\nAn active check defines a series of attacks that, when run against the\ntarget web application, identify susceptibility to specific kinds of\nweakness ([CWE](https://cwe.mitre.org/)). Active checks are run during the\n[active\nscan](https://docs.gitlab.com/ee/user/application_security/dast/browser_based.html#active-scans)\n(full scan) phase of a DAST scan.\n\n\n## What does an active check attack do?\n\n[In-scope](https://docs.gitlab.com/ee/user/application_security/dast/browser_based.html#managing-scope)\nHTTP requests recorded during the crawl phase of the DAST scan are searched\nfor injection locations, places in the request where an attack payload can\nbe injected. Example injection locations include cookie values, request\npaths, query parameters, headers, JSON string values, XML, and inputs\nsubmitted with a form.\n\n\nEach attack defines payloads, which are text or binary content to inject\ninto an HTTP request. Payloads can have prefixes (e.g. `c:\\`) or affixes\n(e.g. `.exe`). Payloads can be an extension of the value originally\nsubmitted with the HTTP request.\n\n\nEvery active check attack will be run against every crawled HTTP request's\ninjection locations. Each injection location may have multiple attack\npayloads injected into it by each attack. Each unique payload injected into\nan injection location becomes a new HTTP request to send to the target web\napplication. HTTP responses to these requests are used to determine if the\nattack succeeded.\n\n\n## Types of attacks\n\nDifferent types of attacks are necessary to detect different kinds of\nweaknesses.\n\n\n### Match response attacks\n\nMatch response attacks send an attack payload with the HTTP request and\nsearch the HTTP response body for unintentionally exposed content. For\nexample, a path traversal attack that uses a payload of `/etc/passwd` might\nlook for evidence of that file in the HTTP response body.\n\n\nMost attacks are match response attacks.\n\n\n### Timing attacks\n\nTiming attacks are useful for blind injection payloads where the success of\nthe attack is determined by how long the target web application took to\nreturn the HTTP response. For example, a SQL injection attack might use a\npayload containing `sleep(15)` to ask the database to pause for 15 seconds\nand determine attack success if the target web application took longer than\n15 seconds to return the HTTP response.\n\n\nNaive timing attacks are prone to false positives due to unpredictable\ntiming delays introduced by factors such as variable internet speeds and\ncached content. To mitigate this, each DAST timing attack uses multiple\npayloads with individual success conditions, and each timing attack must\nsucceed three times in a row to register as a weakness. Timing attacks run\none at a time to prevent one attack from skewing the results of other\nattacks.\n\n\n### Callback attacks\n\nCallback attacks are useful to determine if the target web application\nunintentionally allows data to be exposed to an external entity. For\nexample, a URL in a website query parameter could be injected with the\ncallback server\n`https://site.com/login?redirect-to=https://callback-server.dast/123456789`.\nDAST determines if the target web application unintentionally made an HTTP\nrequest to an untrusted source by asking the callback server if it received\na request with ID `123456789`.\n\n\nThe initial priority for DAST browser-based attacks is on match response and\ntiming attacks. For callback attacks, see [Breach and Attack\nSimulation](https://docs.gitlab.com/ee/user/application_security/).\n\n\n## How are attacks defined?\n\nThe [Vulnerability Research\nteam](/handbook/engineering/development/sec/secure/vulnerability-research/)\nwrites active checks in YAML to minimize the time required to update or add\nnew checks. A simplified example of the 22.1 path traversal attack looks as\nfollows:\n\n\n```yaml\n\nactive_check:\n  attacks:\n    - id: 2\n      type: \"match_response\"\n      description: \"Inject /etc/passwd, report as vulnerable if the response body matches /etc/passwd file contents.\"\n      target_tech: [\"os:unix\"]\n      injection_locations_policy:\n        default:\n          locations:\n            - \"cookie_value\"\n            - \"request_parameter_value\"\n            - \"request_body_parameter_value\"\n            - \"json_value\"\n            - \"xml_value\"\n            - \"multipart_form_data_filename\"\n            - \"multipart_form_data_value\"\n      match_response_attack:\n        payloads: [\"/etc/passwd\"]\n        injections:\n          - template: \"{payload}\"\n          - template: \"{prefix}{payload}{suffix}\"\n            affixes:           \n              - prefix: \"/../../../../../../../../../../../..\"\n                suffix: \"\"\n        matchers:\n          - description: \"Check the HTTP response body to see if it contains the /etc/passwd file contents\"\n            severity: \"High\"\n            match:\n              location: \"response_body\"\n              expression: \"root:.:0:0:\"\n```\n\n\n## Worked example\n\nDuring the DAST crawl phase, DAST submits a form with an input field named\n`file_name` (headers simplified for brevity).\n\n\n```\n\nPOST /read-file HTTP/1.1\n\nAccept: text/html\n\nContent-Length: 20\n\nContent-Type: application/x-www-form-urlencoded\n\nHost: site.com\n\n\nfile_name=browserker\n\n```\n\n\nDuring the active scan phase, DAST creates attacks from crawled HTTP\nrequests. From the above request, injection locations are found for each of\nthe four header values, the request path `/read-file` and the form input\nvalue `browserker`. For a path traversal attack with payload `/etc/passwd`,\nsix attack HTTP requests will be made to the target web application, each\nwith the payload injected into the according injection location.\n\n\nThe attack on the form input value injection location HTTP would be:\n\n\n```\n\nPOST /read-file HTTP/1.1\n\nAccept: text/html\n\nContent-Length: 20\n\nContent-Type: application/x-www-form-urlencoded\n\nHost: site.com\n\n\nfile_name=/etc/passwd\n\n```\n\n\nAssuming the target web application is vulnerable to a path traversal in the\nform input, it might read the contents of `/etc/passwd` and return it in the\nHTTP response, such as:\n\n\n```\n\nHTTP/1.1 200 OK\n\nCache-Control: no-store, no-cache, must-revalidate, proxy-revalidate\n\nContent-Length: 229\n\nContent-Type: text/html; charset=utf-8\n\nDate: Mon, 25 Sep 2023 14:55:20 GMT\n\n\n\u003Chtml>\n\n\u003Cbody>\n  \u003Cdiv id=\"content\">\n    root:x:0:0:root:/root:/bin/bash\n    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\n    bin:x:2:2:bin:/bin:/usr/sbin/nologin\n    sys:x:3:3:sys:/dev:/usr/sbin/nologin\n  \u003C/div>\n\u003C/body>\n\n\u003C/html>\n\n```\n\n\nThe DAST path traversal attack regular expression `root:.:0:0:` matches\nagainst the HTTP response body, so the attack is successful and a new\nfinding is created.\n\n\n[Try GitLab's browser-based DAST\nscanning](https://docs.gitlab.com/ee/user/application_security/dast/browser_based.html).\n",[9,848,1198,719,694],"testing",{"slug":1200,"featured":6,"template":698},"dast-release-first-gitlab-active-check","content:en-us:blog:dast-release-first-gitlab-active-check.yml","Dast Release First Gitlab Active Check","en-us/blog/dast-release-first-gitlab-active-check.yml","en-us/blog/dast-release-first-gitlab-active-check",{"_path":1206,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1207,"content":1213,"config":1219,"_id":1221,"_type":14,"title":1222,"_source":16,"_file":1223,"_stem":1224,"_extension":19},"/en-us/blog/data-driven-decision-making-with-sourcewarp",{"title":1208,"description":1209,"ogTitle":1208,"ogDescription":1209,"noIndex":6,"ogImage":1210,"ogUrl":1211,"ogSiteName":686,"ogType":687,"canonicalUrls":1211,"schema":1212},"SourceWarp: Make data-driven, agile DevSecOps decisions","How the SourceWarp approach and tool help make informed, agile decisions for CI/CD tools and DevSecOps platforms at GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749682686/Blog/Hero%20Images/velocity2.png","https://about.gitlab.com/blog/data-driven-decision-making-with-sourcewarp","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"SourceWarp: Make data-driven, agile DevSecOps decisions\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"GitLab Vulnerability Research Team\"}],\n        \"datePublished\": \"2023-04-13\",\n      }",{"title":1208,"description":1209,"authors":1214,"heroImage":1210,"date":1216,"body":1217,"category":909,"tags":1218},[1215],"GitLab Vulnerability Research Team","2023-04-13","\n\nAt GitLab, we use different strategies to make assessments about the stability\nor robustness of a feature by means of best practices such as staging\nenvironments, feature flags, or canary testing. We also use testing\nstrategies such as [A/B testing](/handbook/marketing/digital-experience/engineering-ab-tests/)\nto assess how users react to feature variants. \n\nHowever, our short release cycles require testing and benchmarking approaches that\nmake it possible to prototype, test, and benchmark ideas quickly (ideally while\ndeveloping them). We need an approach that works on large code\nbases, can help assess a feature **before** deployment to staging or\nproduction, and provides data to support data-driven decision making.\n\nTo address this need, we developed the SourceWarp tool: a record-and-replay framework\nfor source code management systems. In this blog post, we will explain our motivation\nfor creating SourceWarp and explain how we use it to inform data-driven decision making within the GitLab platform.\n\n## Motivation: Data-driven decision making in the DevSecOps context\n\n[DevSecOps](/topics/devsecops/) streamlines software development by allowing teams to ship features quickly\nand providing short feedback cycles for customers. These short feedback cycles can be used to monitor the impact of\na feature from the time it is shipped and inform developers and product\nmanagers about the success or failure of a given deployment.\n\nGitLab, as a heterogeneous DevSecOps platform, acts as an integration point for\ndifferent [CI/CD tools](https://docs.gitlab.com/ee/ci/) that often contribute\nto user-facing functionality. For example, the [vulnerability report](https://docs.gitlab.com/ee/user/application_security/vulnerability_report/),\nwhich displays all detected vulnerabilities, is visible\nas a single functionality, but the data in the report may come from a\nnumber of different tools in various pipelines. The DevSecOps\nplatform collects and stores results in the backend database and keeps track of user actions on the\nfindings (through the UI or the API). A large portion of the automation in the platform\nis built around or initiated by code changes where the\nsource code management system or Git respoitory basically holds the input data. In\norder to test and benchmark new features for these systems effectively, the\ntesting and benchmarking approach needs to have some source code awareness.\n\nWe can use SourceWarp to achieve this. Let's dive in to a real-world example\nof how we used SourceWarp to help make an informed decision about a product integration.\n\n## Case study: Advanced vulnerability tracking\n\nAs a DevSecOps platform, GitLab provides automation\ncentered around code changes, where the source code is stored in a source code\nmanagement system. SourceWarp uses a Git repository as input, which we use to\nsource test-input data to test and benchmark our newly developed feature.\n\nIn a record phase, SourceWarp extracts commits from the source history that are\nrelevant with respect to a given test criterion and generates a patch replay\nsequence. In the monitor phase, SourceWarp replays the generated sequence on a\ntarget system. These phases are executed while continuously monitoring the\nDevSecOps platform to collect metrics and to generate a report that provides\nthe testing and benchmarking results.\n\nWe used SourceWarp to test and benchmark [advanced vulnerability tracking](https://docs.gitlab.com/ee/user/application_security/sast/#advanced-vulnerability-tracking),\nwhich identifies and deduplicates vulnerabilities in a changing code base. In our\nbenchmarking and testing experiment, we let SourceWarp automatically sample patch\nsequences from a slice of GitLab's source code repository history (2020-10-31\nand 2020-12-31) and replay them on two target systems: One system had advanced\nvulnerability tracking enabled, and the other one was using our old\nvulnerability tracking approach.\n\nAfter the application of every patch from the\npatch sequence, SourceWarp collected metrics from the target system that\nrecorded the observed vulnerabilities. We observed that our vulnerability\ntracking approach was 30% more effective than traditional\nvulnerability tracking where `\u003Cfile, line number>` are used to identify the\nlocation of a vulnerabilty. This means that advanced vulnerabiilty tracking\nreduces the manual effort of auditing vulnerabilities by 30%.\n\nIn addition, we\nobserved that with an increasing number of source code changes, the deduplication\neffectiveness of vulnerability tracking increases. Looking at the relatively\nshort timeframe from 2020-10-31 to 2020-12-31, the deduplication effectivness\nincreased from 11% to 30%, which suggests that the effectiveness increases over\ntime as the source code evolves.\n\nSourceWarp performed this experiment in an automated and reproducible way, and\nprovided data that was helpful in making an informed decision about the product\nintegration of vulnerability tracking. \n\n## Where to find more SourceWarp information\n\nThe SourceWarp approach is detailed in our research paper, \"[SourceWarp](/resources/downloads/research-paper-ast2023-sourcewarp.pdf): A scalable, SCM-driven testing and benchmarking approach to support data-driven and agile decision making for CI/CD tools and DevSecOps platforms,\" which will be presented at the 4th ACM/IEEE International Conference on Automation of Software Test ([AST 2023](https://conf.researchr.org/home/ast-2023)). \n\nThe [SourceWarp testing and benchmarking tool](https://gitlab.com/gitlab-org/vulnerability-research/foss/sourcewarp) is implemented in Ruby and is open source (MIT license).\nThe `README.md` provides information about the tool setup and implementation.\nYou can also see it in action in the demo below.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/-9lk_Jhuq14\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n\n## Useful Links\n\n- [Vulnerability Research Team](/handbook/engineering/development/sec/secure/vulnerability-research/)\n- [SourceWarp tool](https://gitlab.com/gitlab-org/vulnerability-research/foss/sourcewarp)\n- [Recorded Demo](https://www.youtube.com/watch?v=-9lk_Jhuq14)\n- [AST 2023](https://conf.researchr.org/home/ast-2023)\n- [Research Paper](/resources/downloads/research-paper-ast2023-sourcewarp.pdf)\n\nCover image by [Jason Corey](https://unsplash.com/@jason_corey_) on [Unsplash](https://unsplash.com/photos/AT5vuPoi8vc)\n{: .note}\n",[9,109,694],{"slug":1220,"featured":6,"template":698},"data-driven-decision-making-with-sourcewarp","content:en-us:blog:data-driven-decision-making-with-sourcewarp.yml","Data Driven Decision Making With Sourcewarp","en-us/blog/data-driven-decision-making-with-sourcewarp.yml","en-us/blog/data-driven-decision-making-with-sourcewarp",{"_path":1226,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1227,"content":1233,"config":1239,"_id":1241,"_type":14,"title":1242,"_source":16,"_file":1243,"_stem":1244,"_extension":19},"/en-us/blog/debug-web-apps-quickly-within-gitlab",{"title":1228,"description":1229,"ogTitle":1228,"ogDescription":1229,"noIndex":6,"ogImage":1230,"ogUrl":1231,"ogSiteName":686,"ogType":687,"canonicalUrls":1231,"schema":1232},"Debug Web apps quickly within GitLab","Jam for GitLab, a browser extension, creates GitLab issues with critical context such as browser info, console/network logs, and reproduction steps - in one click.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099168/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%2810%29_arHGAEPyRHF7euCvaxE0S_1750099168482.png","https://about.gitlab.com/blog/debug-web-apps-quickly-within-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Debug Web apps quickly within GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Ivanha Paz\"}],\n        \"datePublished\": \"2024-05-08\",\n      }",{"title":1228,"description":1229,"authors":1234,"heroImage":1230,"date":1122,"body":1236,"category":909,"tags":1237},[1235],"Ivanha Paz","***Editor's note: From time to time, we invite members of the community to contribute to the GitLab Blog. Thanks to [Jam.dev](https://jam.dev/gitlab) for co-creating with us.***\n\nDebugging a Web app takes a village but gathering information about bugs as they happen can be challenging. Jam.dev launched the Jam for GitLab browser extension (available for Google Chrome, Arc, Opera, and Edge) that enables all DevSecOps team members to create comprehensive debugging reports, complete with instant replays of the bug, with a single click. \n\nThe reports, which are spun up as GitLab issues, include the context engineers need to find and fix bugs, including internet speed, browser information, console/network logs, and reproduction steps. Jam also parses GraphQL requests for errors which can be copied as cURL.\n\nJam for GitLab was built using GitLab's API so it is fully integrated with the DevSecOps platform. Here’s how Jam for GitLab works:\n\n1. Click on the Jam browser extension to record your screen and take a screenshot or replay a bug that just happened. \n\n![Create issue - gif 2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099178/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750099177866.gif)\n\n2. Jam automatically generates a GitLab issue with all the technical debugging context.\n\n![Info collected - gif 1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099178/Blog/Content%20Images/Blog/Content%20Images/Jam_for_GitLab_debugging_aHR0cHM6_1750099177867.gif)\n\n## Why we created Jam for GitLab\nLike so many of you, we are huge fans of GitLab. A lot of Jam users love and engage with the GitLab developer community. It’s one of Jam’s top 3 most requested integrations! And with their API, GitLab makes it easy for startups like us to build new tools in the GitLab ecosystem. Building for the GitLab community is an important milestone for the Jam team. \n\nJust like GitLab values efficiency, we want to make developers’ lives easier. We believe the best way to do it is by removing a lot of unnecessary barriers for collaboration between engineering and product. We share this vision with GitLab and all of you using it to improve the lives of your customers; and quite literally build the future. \n\nLike my teammate and Jam engineer, Arég, says, “The worst part of the job is trying to debug an existing system to understand why it’s not behaving the way people expect. But you can use Jam, and maybe it’ll be less terrible, and you’ll have more time to do the best part: building something new.”\n\nGitLab is where product teams come together to build what’s next. Not just engineers, but everyone involved in the software development lifecycle. It takes a powerful platform to enable this level of collaboration. We love what GitLab stands for, and it’s truly an honor to contribute to our shared mission by making debugging easier and faster.\n\nFrom all of us at Jam, thank you to the GitLab team for being such awesome people to work with and building a product we and millions around the world love.\n\n> Ready to dramatically cut your debugging time? [Get started with Jam today.](https://jam.dev/gitlab)\n\n*Paz is DevRel lead at Jam.*\n",[233,1238,9],"code review",{"slug":1240,"featured":6,"template":698},"debug-web-apps-quickly-within-gitlab","content:en-us:blog:debug-web-apps-quickly-within-gitlab.yml","Debug Web Apps Quickly Within Gitlab","en-us/blog/debug-web-apps-quickly-within-gitlab.yml","en-us/blog/debug-web-apps-quickly-within-gitlab",{"_path":1246,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1247,"content":1253,"config":1260,"_id":1262,"_type":14,"title":1263,"_source":16,"_file":1264,"_stem":1265,"_extension":19},"/en-us/blog/deploy-a-server-using-go-with-gitlab-google-cloud",{"title":1248,"description":1249,"ogTitle":1248,"ogDescription":1249,"noIndex":6,"ogImage":1250,"ogUrl":1251,"ogSiteName":686,"ogType":687,"canonicalUrls":1251,"schema":1252},"Deploy a server using Go with GitLab + Google Cloud","This tutorial shows how to use GitLab’s Google Cloud integration to deploy a Golang server in less than 10 minutes, helping developers become more independent and efficient.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098028/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945_fJKX41PJHKCfSOWw4xQxm_1750098028126.png","https://about.gitlab.com/blog/deploy-a-server-using-go-with-gitlab-google-cloud","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Deploy a server using Go with GitLab + Google Cloud\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Claire Champernowne\"},{\"@type\":\"Person\",\"name\":\"Noah Ing\"}],\n        \"datePublished\": \"2025-01-28\",\n      }",{"title":1248,"description":1249,"authors":1254,"heroImage":1250,"date":1256,"body":1257,"category":848,"tags":1258},[1255,821],"Claire Champernowne","2025-01-28","Deploying an application to the cloud often requires assistance from production or DevOps engineers. GitLab's Google Cloud integration empowers developers to handle deployments independently. In this tutorial, you'll learn how to deploy a server to Google Cloud in less than 10 minutes using Go. Whether you’re a solo developer or part of a large team, this setup allows you to deploy applications efficiently.\n\n## You'll learn how to:\n\n1. Create a new project in GitLab\n2. Create a Go server utilizing `main.go`\n3. Use the Google Cloud integration to create a Service account\n4. Use the Google Cloud integration to create Cloud Run via a merge request\n5. Access your newly deployed Go server\n6. Clean up your environment\n\n## Prerequisites\n\n- Owner access on a Google Cloud Platform project\n- Working knowledge of Golang\n- Working knowledge of GitLab CI\n- 10 minutes\n\n## Step-by-step Golang server deployment to Google Cloud\n\n### 1. Create a new blank project in GitLab.\n\nWe decided to call our project `golang-cloud-run` for simplicity.\n\n![Create a new blank project in GitLab](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098035/Blog/Content%20Images/Blog/Content%20Images/image9_aHR0cHM6_1750098035249.png)\n\n### 2. Create a server utilizing this `main.go` demo.\n\nFind the `main.go` demo [here](https://gitlab.com/demos/applications/golang-cloud-run).\n\n```\n// Sample run-helloworld is a minimal Cloud Run service.\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\tlog.Print(\"starting server...\")\n\thttp.HandleFunc(\"/\", handler)\n\n\t// Determine port for HTTP service.\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t\tlog.Printf(\"defaulting to port %s\", port)\n\t}\n\n\t// Start HTTP server.\n\tlog.Printf(\"listening on port %s\", port)\n\tif err := http.ListenAndServe(\":\"+port, nil); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tname := os.Getenv(\"NAME\")\n\tif name == \"\" {\n\t\tname = \"World\"\n\t}\n\tfmt.Fprintf(w, \"Hello %s!\\n\", name)\n}\n```\n\n### 3. Use the Google Cloud integration to create a Service account.\n\nNavigate to **Operate \\> Google Cloud \\> Create Service account**.\n\n![Golang tutorial - image 2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098036/Blog/Content%20Images/Blog/Content%20Images/image11_aHR0cHM6_1750098035250.png)\n\n### 4. Configure the region you would like the Cloud Run instance deployed to.\n\n![Golang tutorial - image10](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098035/Blog/Content%20Images/Blog/Content%20Images/image10_aHR0cHM6_1750098035252.png)\n\n### 5. Use the Google Cloud integration to configure Cloud Run via Merge Request.\n\n![Golang tutorial - image4](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098035/Blog/Content%20Images/Blog/Content%20Images/image4_aHR0cHM6_1750098035254.png)\n\n### 6. This will open a merge request. Immediately merge the MR.\n\n![Golang tutorial - image6](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098036/Blog/Content%20Images/Blog/Content%20Images/image6_aHR0cHM6_1750098035257.png)\n\nThis merge request adds a CI/CD deployment job to your pipeline definition. In our case, this is also creating a pipeline definition, as we didn’t have one before.\n\n**Note:** The CI/CD variables `GCP_PROJECT_ID`, `GCP_REGION`, `GCP_SERVICE_ACCOUNT`, `GCP_SERVICE_ACCOUNT_KEY` will all be automatically populated from the previous steps. \n\n![Golang tutorial - image7](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098035/Blog/Content%20Images/Blog/Content%20Images/image7_aHR0cHM6_1750098035259.png)\n\n### 7. Voila! Check your pipeline and you will see you have successfully deployed to Google Cloud Run utilizing GitLab CI.\n\n![Golang tutorial - image2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098035/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098035261.png)\n\n\u003Cbr>\n\n![Golang tutorial - image3](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098035/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750098035262.png)\n\n## 8. Click the Service URL to view your newly deployed server.\n\nAlternatively, you can navigate to **Operate \\> Environments** to see a list of deployments for your environments.\n\n![Golang tutorial - image5](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098035/Blog/Content%20Images/Blog/Content%20Images/image5_aHR0cHM6_1750098035264.png)\n\nBy clicking on the environment called **main**, you’ll be able to view a complete list of deployments specific to that environment.\n\n![Golang tutorial - image8](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098035/Blog/Content%20Images/Blog/Content%20Images/image8_aHR0cHM6_1750098035265.png)\n\n## Next steps\n\nTo get started with developing your Go application, try adding another endpoint. For instance, in your `main.go` file, you can add a `/bye` endpoint as shown below (don’t forget to register the new handler function in main!):\n\n```\nfunc main() {\n\tlog.Print(\"starting server...\")\n\n\thttp.HandleFunc(\"/\", handler)\n\thttp.HandleFunc(\"/bye\", byeHandler)\n```\n\n```\nfunc byeHandler(w http.ResponseWriter, r *http.Request) {\n\tname := os.Getenv(\"NAME\")\n\tif name == \"\" {\n\t\tname = \"World\"\n\t}\n\tfmt.Fprintf(w, \"Bye %s!\\n\", name)\n}\n```\n\nYour `main.go` file should now look something like this:\n\n```\n// Sample run-helloworld is a minimal Cloud Run service.\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n)\n\nfunc main() {\n\tlog.Print(\"starting server...\")\n\n\thttp.HandleFunc(\"/\", handler)\n\n\thttp.HandleFunc(\"/bye\", byeHandler)\n\n\t// Determine port for HTTP service.\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t\tlog.Printf(\"defaulting to port %s\", port)\n\t}\n\n\t// Start HTTP server.\n\tlog.Printf(\"listening on port %s\", port)\n\tif err := http.ListenAndServe(\":\"+port, nil); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tname := os.Getenv(\"NAME\")\n\tif name == \"\" {\n\t\tname = \"World\"\n\t}\n\tfmt.Fprintf(w, \"Hello %s!\\n\", name)\n}\n\nfunc byeHandler(w http.ResponseWriter, r *http.Request) {\n\tname := os.Getenv(\"NAME\")\n\tif name == \"\" {\n\t\tname = \"World\"\n\t}\n\tfmt.Fprintf(w, \"Bye %s!\\n\", name)\n}\n```\n\nPush the changes to the repo, and watch the `deploy-to-cloud-run job` deploy the updates. Once it’s complete, go back to the Service URL and navigate to the `/bye` endpoint to see the new functionality in action.\n\n## Clean up the environment\n\nTo prevent incurring charges on your Google Cloud account for the resources used in this tutorial, you can either delete the specific resources or delete the entire Google Cloud project. For detailed instructions, refer to the [cleanup guide](https://docs.gitlab.com/ee/tutorials/create_and_deploy_web_service_with_google_cloud_run_component/#clean-up).\n\n> Discover more tutorials like this in our [Solutions Architecture](https://about.gitlab.com/blog/tags/solutions-architecture/) area.\n",[9,496,827,1259,848,719],"solutions architecture",{"slug":1261,"featured":6,"template":698},"deploy-a-server-using-go-with-gitlab-google-cloud","content:en-us:blog:deploy-a-server-using-go-with-gitlab-google-cloud.yml","Deploy A Server Using Go With Gitlab Google Cloud","en-us/blog/deploy-a-server-using-go-with-gitlab-google-cloud.yml","en-us/blog/deploy-a-server-using-go-with-gitlab-google-cloud",{"_path":1267,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1268,"content":1274,"config":1279,"_id":1281,"_type":14,"title":1282,"_source":16,"_file":1283,"_stem":1284,"_extension":19},"/en-us/blog/develop-c-unit-testing-with-catch2-junit-and-gitlab-ci",{"title":1269,"description":1270,"ogTitle":1269,"ogDescription":1270,"noIndex":6,"ogImage":1271,"ogUrl":1272,"ogSiteName":686,"ogType":687,"canonicalUrls":1272,"schema":1273},"Develop C++ unit testing with Catch2, JUnit, and GitLab CI","Learn how to set up, write, and automate C++ unit tests using Catch2 with GitLab CI/CD. See examples from a working air quality app project and AI-powered help from GitLab Duo.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659684/Blog/Hero%20Images/AdobeStock_479904468__1_.jpg","https://about.gitlab.com/blog/develop-c-unit-testing-with-catch2-junit-and-gitlab-ci","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Develop C++ unit testing with Catch2, JUnit, and GitLab CI\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Fatima Sarah Khalid\"}],\n        \"datePublished\": \"2024-07-02\",\n      }",{"title":1269,"description":1270,"authors":1275,"heroImage":1271,"date":1276,"body":1277,"category":10,"tags":1278},[713],"2024-07-02","Continuous integration (CI) and automated testing are important DevSecOps workflows for software developers to detect bugs early, improve code quality, and streamline their development processes. \n\nIn this tutorial, you'll learn how to set up unit testing on a `C++` project with [Catch2](https://github.com/catchorg/Catch2) and GitLab CI for continuous integration. You'll also see how the AI-powered features of [GitLab Duo](https://about.gitlab.com/gitlab-duo/) can help. We’ll use [an air quality monitoring application](https://gitlab.com/gitlab-da/use-cases/ai/ai-applications/air-quality-app) as our reference project.\n\n## Prerequisites\n\n- Ensure you have [CMake](https://cmake.org/ \"CMake\") installed on your machine. \n- A modern `C++` compiler such as GCC or Clang is required. \n- An API key from [OpenWeatherMap](https://openweathermap.org/api) - requires signing up for a free account (1,000/calls per day are included for free). \n\n## Set up the application for testing\n\nThe reference project we’ll be using for demonstrating testing in this blog post is an air quality monitoring application that fetches air quality data from the OpenWeatherMap API based on the U.S zip codes only provided by the user.\n\nHere are the steps to set up the application for testing:\n\n1. Fork the [the reference project](https://gitlab.com/gitlab-da/use-cases/ai/ai-applications/air-quality-app) and clone the fork to your local environment.\n\n2. Generate an API key from  [OpenWeatherMap](https://openweathermap.org/) and export it into the environment. \n\n```shell\nexport API_KEY=\"YOURAPIKEY_HERE\"\n```\n\n3. Alternatively, you can add the key into your `.env` configuration, and source it with `source ~/.env`, or use a different mechanism to populate the environment.\n\n4. Compile and build the project code with the following instructions:\n\n```cpp\ncmake -S . -B build\ncmake --build build\n```\n\n5. Run the application using the executable and passing in a U.S zip code (90210 as an example): \n\n```cpp\n./build/air_quality_app 90210\n```\n\nHere’s an example of what running the program will look like in your terminal:  \n\n```bash\n❯ ./build/air_quality_app 90210\nAir Quality Index (AQI) for Zip Code 90210: 2 (Fair)\n```\n\n## Install Catch2\n\nNow that the application is set up and working, let's start working on adding testing using Catch2. Catch2 is a modern, `C++-native` testing framework for unit tests. \n\nYou can also ask GitLab Duo Chat within your IDE for an introduction to getting started with Catch2 as a `C++` testing framework. GitLab Duo Chat will provide getting started steps as well as an example test: \n\n![GitLab Duo Chat starting steps and example test](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749676997/Blog/Content%20Images/1.duo-chat-installing-catch2.png)\n\n1. First navigate to your project’s root directory and create an externals folder using the `mkdir` command.\n\n```shell\nmkdir externals\n```\n\n2. There are several ways to install Catch2 via [its CMake integration](https://github.com/catchorg/Catch2/blob/devel/docs/cmake-integration.md#top). We will use the option of installing it as a submodule and including it as part of the source code to simplify dependency management. To add Catch2 to your project in the `externals` folder: \n\n```shell\ngit submodule add https://github.com/catchorg/Catch2.git externals/Catch2\ngit submodule update --init --recursive\n```\n\n3. Update `CMakeLists.txt` to include Catch2’s directory as a subdirectory. This allows CMake to find and build Catch2 as a part of our project. \n\n```cpp\n# Assuming Catch2 in externals/Catch2\nadd_subdirectory(externals/Catch2)\n```\n\n4. Create a `tests.cpp` file in your project root to write our tests to: \n\n```shell\ntouch tests.cpp\n```\n\n5. Update `CMakeLists.txt` Link against Catch2. When defining your test executable in CMake, link it against Catch2:\n\n```cpp\n# Add tests executable and link it to Catch2\nadd_executable(tests test.cpp)\ntarget_link_libraries(tests PRIVATE Catch2::Catch2WithMain)\n```\n\n## Structure the project for testing\n\nBefore we start writing our tests, we should separate our application logic into separate files in order to maintain and test our code more efficiently. At the end of this section we should have:\n\n```\nmain.cpp containing only the main() function and application setup\nincludes/functions.cpp containing all functional code such as API calls and data processing: \nincludes/functions.h containing the declarations for the functions defined in functions.cpp.  It needs to define the preprocessor macro guards, and include all necessary headers. \n```\n\nApply the following changes to the files: \n\n1. `main.cpp`\n\n```cpp\n#include \u003Ciostream>\n#include \"functions.h\"\n\nint main(int argc, char* argv[]) {\n   if (argc \u003C 2) {\n       std::cerr \u003C\u003C \"Usage: \" \u003C\u003C argv[0] \u003C\u003C \" \u003CZip Code>\" \u003C\u003C std::endl;\n       return 1;\n   }\n\n   std::string zipCode = argv[1];\n   std::string apiKey = getApiKey();\n   if (apiKey.empty()) {\n       std::cerr \u003C\u003C \"API key not found.\" \u003C\u003C std::endl;\n       return 1;\n   }\n\n   auto [lat, lon] = geocodeZipcode(zipCode, apiKey);\n   if (lat == 0 && lon == 0) {\n       std::cerr \u003C\u003C \"Failed to geocode zipcode.\" \u003C\u003C std::endl;\n       return 1;\n   }\n\n   std::string response = fetchAirQuality(lat, lon, apiKey);\n   std::string airQualityInfo = parseAirQualityResponse(response);\n\n   std::cout \u003C\u003C \"Air Quality Index for Zip Code \" \u003C\u003C zipCode \u003C\u003C \": \" \u003C\u003C airQualityInfo \u003C\u003C std::endl;\n\n   return 0;\n}\n```\n\n2. Create a `functions.h:` in the `includes` folder: \n\n```cpp\n#ifndef FUNCTIONS_H\n#define FUNCTIONS_H\n\n#include \u003Cstring>\n#include \u003Cutility>\n#include \u003Cvector>\n\n// Declare the function prototype\nstd::string httpRequest(const std::string& url);\nbool loadEnvFile(const std::string& filename);\nstd::string getApiKey();\nstd::pair\u003Cdouble, double> geocodeZipcode(const std::string& zipCode, const std::string& apiKey);\nstd::string fetchAirQuality(double lat, double lon, const std::string& apiKey);\nstd::string parseAirQualityResponse(const std::string& response);\n\n#endif\n```\n\n3. Create a `functions.cpp` in the `includes` folder: \n\n```cpp\n#include \"functions.h\"\n#include \u003Cfstream>\n#include \u003Celnormous/HTTPRequest.hpp>\n#include \u003Cnlohmann/json.hpp>\n#include \u003Ciostream>\n#include \u003Ccstdlib> // For getenv\n\nstd::string httpRequest(const std::string& url) {\n   try {\n       http::Request request{url};\n       const auto response = request.send(\"GET\");\n       return std::string{response.body.begin(), response.body.end()};\n   } catch (const std::exception& e) {\n       std::cerr \u003C\u003C \"Request failed, error: \" \u003C\u003C e.what() \u003C\u003C std::endl;\n       return \"\";\n   }\n}\nstd::string getApiKey() {\n   const char* envApiKey = std::getenv(\"API_KEY\");\n   if (envApiKey) {\n       return std::string(envApiKey);\n   }\n   // If the environment variable is not set, fallback to the config file\n   std::ifstream configFile(\"config.txt\");\n   std::string line;\n   if (getline(configFile, line)) {\n       return line.substr(line.find('=') + 1);\n   }\n   return \"\";\n}\n\nstd::pair\u003Cdouble, double> geocodeZipcode(const std::string& zipCode, const std::string& apiKey) {\n   std::string url = \"http://api.openweathermap.org/geo/1.0/zip?zip=\" + zipCode + \",US&appid=\" + apiKey;\n   std::string response = httpRequest(url);\n   try {\n       auto json = nlohmann::json::parse(response);\n       if (json.contains(\"lat\") && json.contains(\"lon\")) {\n           double lat = json[\"lat\"];\n           double lon = json[\"lon\"];\n           return {lat, lon};\n       } else {\n           std::cerr \u003C\u003C \"Geocode response missing 'lat' or 'lon' fields: \" \u003C\u003C response \u003C\u003C std::endl;\n       }\n   } catch (const nlohmann::json::parse_error& e) {\n       std::cerr \u003C\u003C \"Failed to parse geocode response: \" \u003C\u003C e.what() \u003C\u003C \" - Response: \" \u003C\u003C response \u003C\u003C std::endl;\n   }\n   return {0, 0};\n}\n\nstd::string fetchAirQuality(double lat, double lon, const std::string& apiKey) {\n   std::string url = \"http://api.openweathermap.org/data/2.5/air_pollution?lat=\" + std::to_string(lat) + \"&lon=\" + std::to_string(lon) + \"&appid=\" + apiKey;\n   std::string response = httpRequest(url);\n   return response;\n}\n\nstd::string parseAirQualityResponse(const std::string& response) {\n   try {\n       auto json = nlohmann::json::parse(response);\n       if (json.contains(\"list\") && !json[\"list\"].empty() && json[\"list\"][0].contains(\"main\")) {\n           int aqi = json[\"list\"][0][\"main\"][\"aqi\"];\n           std::string aqiCategory;\n           switch (aqi) {\n               case 1:\n                   aqiCategory = \"Good\";\n                   break;\n               case 2:\n                   aqiCategory = \"Fair\";\n                   break;\n               case 3:\n                   aqiCategory = \"Moderate\";\n                   break;\n               case 4:\n                   aqiCategory = \"Poor\";\n                   break;\n               case 5:\n                   aqiCategory = \"Very Poor\";\n                   break;\n               default:\n                   aqiCategory = \"Unknown\";\n                   break;\n           }\n           return std::to_string(aqi) + \" (\" + aqiCategory + \")\";\n       } else {\n           return \"No AQI data available\";\n       }\n   } catch (const std::exception& e) {\n       std::cerr \u003C\u003C \"Failed to parse JSON response: \" \u003C\u003C e.what() \u003C\u003C std::endl;\n       return \"Error parsing AQI data\";\n   }\n}\n\n```\n\n4. Now that we have separated the source files, we also need to update our `CMakeLists.txt` to include `functions.cpp` in the `add_executable()` calls:\n\n```cpp\ncmake_minimum_required(VERSION 3.14)\nproject(air-quality-app)\n\n# Set the C++ standard for the project\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\ninclude_directories(${CMAKE_SOURCE_DIR}/includes)\n\n# Define the main program executable\nadd_executable(air_quality_app main.cpp includes/functions.cpp)\n\n# Assuming Catch2 in externals/Catch2\nadd_subdirectory(externals/Catch2)\n\n# Add tests executable and link it to Catch2\nadd_executable(tests tests.cpp includes/functions.cpp)\ntarget_link_libraries(tests PRIVATE Catch2::Catch2WithMain)\n```\n\nTo verify that the changes are working, regenerate the CMake configuration and rebuild the source code with the following commands. The build will take longer now that we're compiling Catch2 files. \n\n```shell\nrm -rf build # delete existing build files\ncmake -S . -B build \ncmake --build build  \n```\n\nYou should be able to run the application without any errors.\n\n```shell\n./build/air_quality_app 90210\n```\n\n## Write tests in Catch2  \n\nCatch2 tests are made up of [macros and assertions](https://github.com/catchorg/Catch2/blob/devel/docs/assertions.md). Macros in Catch2 are used to define test cases and sections within those test cases. They help in organizing and structuring the tests. Assertions are used to verify that the code behaves as expected. If an assertion fails, the test case will fail, and Catch2 will report the failure.\n\nLet’s review a basic test scenario for an addition function to understand. Note: This test is read-only, as an example. \n\n```cpp\nint add(int a, int b) {\n   return a + b;\n}\n\nTEST_CASE(\"Addition works correctly\", \"[math]\") {\n   REQUIRE(add(1, 1) == 2);  // Test passes if 1+1 equals 2\n   REQUIRE(add(2, 2) != 5);  // Test passes if 2+2 does not equal 5\n}\n```\n\n- Each test begins with the `TEST_CASE` macro, which defines a test case container. The macro accepts two parameters: a string describing the test case and optionally a second string for tagging the test for easy filtering.\n- Tests are also composed of assertions, which are statements that check if conditions are true. Catch2 provides macros for assertion that include `REQUIRE`, which aborts the current test if the assertion fails, and `CHECK`, which logs the failure but continues with the current test.\n\n### Prepare to write tests with Catch2\n\nTo test the API retrieval functions in our air quality application, we’ll be using mock API requests. Mock API testing is a technique used to test how your application will interact with an external API without making any real API calls. Instead of sending requests to a live API server, we can simulate the responses using predefined data. Mock requests allow us to control the input data and specify exactly what the API would return for different requests, making sure that our tests aren't affected by changes in the real API responses or unexpected data. This also makes it easier for us to simulate and catch different failures.\n\nIn our `tests.cpp` file, let’s define the following function to run mock API requests.   \n\n```cpp\n#include \"includes/functions.h\"\n#include \u003Ccatch2/catch_test_macros.hpp>\n#include \u003Cstring>\n\n// Mock HTTP request function that simulates API responses\nstd::string mockHttpRequest(const std::string& url) {\n   if (url.find(\"geo\") != std::string::npos) {\n       // Mock response for geocoding\n       return R\"({\"lat\": 40.7128, \"lon\": -74.0060})\"; \n   } else if (url.find(\"air_pollution\") != std::string::npos) {\n       // Mock response for air quality\n       return R\"({\"list\": [{\"main\": {\"aqi\": 2}}]})\";\n   }\n   // Default mock response for unmatched endpoints\n   return \"{}\";\n}\n// Overriding the actual httpRequest function with the mockHttpRequest for testing\nstd::string httpRequest(const std::string& url) {\n   return mockHttpRequest(url);\n}\n```\n\n- This function simulates HTTP requests and returns predefined JSON responses based on the URL given as input. \n- It also checks the URL to determine which type of data is being requested based on the functionality of the application (geocoding, air pollution, or forecast data). If the URL doesn’t match the expected endpoint, it returns an empty JSON object. \n\nDon't compile the code just yet, as you'll see a linker error. Since we're overriding the original `httpRequest` function with our mock function for testing, we'll need a preprocessor macro to enable conditional compilation - indicating which `httpRequest` function should run when we're compiling tests. \n\n#### Define a preprocessor macro for testing  \n\nBecause we’ve overridden `httpRequest` in our `tests.cpp`, we need to exclude that code from `functions.cpp` when we’re testing. When building tests, we may need to ensure that certain parts of our code behave differently or are excluded. We can do this by defining a preprocessor macro `TESTING` which enables conditional compilation, allowing us to selectively include or exclude code when compiling the test target:  \n\nWe define the `TESTING` macro in our `CMakeLists.txt` at the end:  \n\n```cpp\n# Define TESTING macro for this target\ntarget_compile_definitions(tests PRIVATE TESTING)\n```\n\nAnd add the macro wrapper in  `functions.cpp` around the original `httpRequest` function:  \n\n```cpp\n#ifndef TESTING  // Exclude this part when TESTING is defined\nstd::string httpRequest(const std::string& url) {\n   try {\n       http::Request request{url};\n       const auto response = request.send(\"GET\");\n       return std::string{response.body.begin(), response.body.end()};\n   } catch (const std::exception& e) {\n       std::cerr \u003C\u003C \"Request failed, error: \" \u003C\u003C e.what() \u003C\u003C std::endl;\n       return \"\";\n   }\n}\n#endif\n```\n\nRegenerate the CMake configuration and rebuild the source code to verify it works.\n\n```shell\ncmake --build build  \n```\n\n### Write the first tests \n\nNow, let’s write some tests for our air quality application.\n\n#### Test 1: Verify API key retrieval \n\nThis test ensures that the `getApiKey` function retrieves the API key correctly from the environment variable or the configuration file. Add the test case to our `tests.cpp`:\n\n```cpp\n\nTEST_CASE(\"API Key Retrieval\", \"[api]\") {\n   // Set the API_KEY environment variable for testing\n   setenv(\"API_KEY\", \"test_key\", 1);\n   // Test if the key is retrieved correctly\n   REQUIRE(getApiKey() == \"test_key\");\n}\n```\n\nYou can verify that this tests passes by rebuilding the code and running the tests:\n\n```shell\ncmake --build build\n./build/tests\n```\n\n#### Test 2: Geocode the zip code\n\nThis test ensures that the `geocodeZipcode` function returns the correct latitude and longitude for a given zip code using the mock API response function we set up earlier. The  `geocodeZipcode` function is supposed to hit an API that returns geographic coordinates based on a zip code. \n\nIn `tests.cpp`, add this test case for the zip code 90210: \n\n```cpp\nTEST_CASE(\"Geocode Zip code\", \"[geocode]\") {\n   std::string apiKey = \"test_key\";\n   std::pair\u003Cdouble, double> coordinates = geocodeZipcode(\"90210\", apiKey);\n   // Check latitude\n   REQUIRE(coordinates.first == 40.7128);\n   // Check longitude \n   REQUIRE(coordinates.second == -74.0060);\n}\n```\n\nThe purpose of this test is to verify that the function `geocodeZipcode` can correctly parse the latitude and longitude from the API response. By hardcoding the expected response, we ensure that the test environment is controlled and predictable.\n\n #### Test 3: Air quality API test\n\nThis test ensures that the `fetchAirQuality` function correctly fetches air quality data using the mock API response function we set up earlier. It verifies that the function constructs the API request properly, sends it, and accurately parses the air quality index (AQI) from the mock JSON response. This validation helps ensure that the overall process of fetching and interpreting air quality data works as intended.\n\n```cpp\nTEST_CASE(\"Fetch Air Quality\", \"[airquality]\") {\n   std::string apiKey = \"test_key\";\n   double lat = 40.7128;\n   double lon = -74.0060;\n   std::string response = fetchAirQuality(lat, lon, apiKey);\n   // Check the response\n   REQUIRE(response == R\"({\"list\": [{\"main\": {\"aqi\": 2}}]})\");\n}\n```\n\n## Build and run the tests\n\nTo  build and compile our application, we'll use the same CMake commands as before:\n\n```cpp\ncmake -S . -B build\ncmake --build build\n\n```\n\nAfter building, we can run our tests by executing the test binary:  \n\n```cpp\n./build/tests\n\n```\n\nRunning this command will execute all defined tests, and you will see output indicating whether each test has passed or failed.\n\n![Output showing pass/fail of tests](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749676998/Blog/Content%20Images/2.running-catch2-tests.png)\n\n## Set up GitLab CI/CD\n\nTo automate the testing process each time we push some new code to our repository, let’s set up [GitLab CI/CD](https://about.gitlab.com/topics/ci-cd/). Create a new `.gitlab-ci.yml` configuration file in the root directory. \n\n```yaml\nimage: gcc:latest\n\nvariables:\n GIT_SUBMODULE_STRATEGY: recursive\n\nstages:\n - build\n - test\n\nbefore_script:\n - apt-get update && apt-get install -y cmake\n\ncompile:\n stage: build\n script:\n   - cmake -S . -B build\n   - cmake --build build\n artifacts:\n   paths:\n     - build/\n\ntest:\n stage: test\n script:\n   - ./build/tests --reporter junit -o test-results.xml\n artifacts:\n   reports:\n     junit: test-results.xml\n```\n\nThis CI/CD configuration will compile both the main application and the test suite, then run the tests, generating a JUnit XML report which GitLab uses to display the test results.  \n\n- In `before_script`, we added an installation for `cmake`, and `git submodule sync --recursive` which initializes and updates our submodules (catch2). \n- In the `test` stage, `--reporter junit -o test-results.xml` specifies that the test results should be treated as a JUnit report which allows GitLab CI to display results in the UI. This is super helpful when you have several tests in your application.  \n\nWe also need to [add an environmental variable](https://docs.gitlab.com/ee/ci/variables/#define-a-cicd-variable-in-the-ui) with the `API_KEY` in project settings on GitLab.\n\nDon’t forget to add all new files to Git, and commit and push the changes in a new MR:\n\n```shell\ngit checkout -b tests-catch2-cicd\n\ngit add includes/functions.{h,cpp} tests.cpp .gitlab-ci.yml \ngit add CMakeLists.txt main.cpp \n\ngit commit -vm “Add Catch2 tests and CI/CD configuration”\ngit push \n```\n\n## View the test report\n\nAfter pushing our code changes, we can review the results of our tests in the GitLab UI in the Pipeline view in the `Tests` tab:\n\n![GitLab pipeline view shows test results](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749676998/Blog/Content%20Images/2.0-passed-tests-UI.png)\n\n## Simulate a test failure\n\nTo demonstrate how our UI will handle test failures, we can intentionally introduce a bug into our code and observe the resulting behavior. \n\nLet's modify our `parseAirQualityResponse` function to introduce an error. We can change the AQI category for an AQI value of 2 from \"Fair\" to \"Poor.\" This change will cause the related test to fail, allowing us to see the test failure in the GitLab UI.\n\nIn `functions.cpp`, find the `parseAirQualityResponse` function and modify the switch statement for case `2` to set the `Poor` value instead of `Fair`:\n\n```cpp\n               // Intentional bug:\n               case 2:\n                   aqiCategory = \"Poor\";\n                   break;\n```\n\nIn tests.cpp, add a new test case that directly checks the output of the `parseAirQualityResponse` function. This test ensures that the `parseAirQualityResponse` function correctly parses and categorizes the air quality data from the mock API response. This function takes a JSON response, extracts the AQI value, and translates it into a human-readable category.\n\n```cpp\n\nTEST_CASE(\"Parse Air Quality Response\", \"[airquality]\") {\n   std::string mockResponse = R\"({\"list\": [{\"main\": {\"aqi\": 2}}]})\";\n   std::string result = parseAirQualityResponse(mockResponse);\n   // This should fail due to the intentional bug\n   REQUIRE(result == \"2 (Fair)\");\n}\n\n```\n\nCommit the changes, and push them into the MR. Open the MR in your browser. \n\nBy introducing an intentional bug in this function, we can see how a test failure is reported in GitLab's pipelines UI. We must add, commit, and push the changes to our repository to view the test failure in the pipeline. \n\n![Simulated test failure](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749676998/Blog/Content%20Images/2.1-failed-test-simulation.png)\n\n![Details of the simulated failed test](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749676998/Blog/Content%20Images/2.2-failed-test-simulation-details.png)\n\nOnce we've verified this simulated test failure, we can use `git revert` to roll back that commit. \n\n```shell\ngit revert\n```\n\n## Add and test a new feature\n\nLet’s put what you've learned together by creating a new feature in the air quality application and then writing a test for that feature using Catch2. The new feature will fetch the current weather forecast for the provided zip code.\n\nFirst, we'll define a `Weather` struct and add the function prototype in our `functions.h` file (inside the `#endif`):\n\n```cpp\n\nstruct Weather {\n   std::string main;\n   std::string description;\n   double temperature;\n};\n\nWeather getCurrentWeather(const std::string& apiKey, double lat, double lon);\n```\n\nThen, we implement the `getCurrentWeather` function in `functions.cpp`. This function calls the OpenWeatherMap API to retrieve the current weather and parses the JSON response. This code was generated using [GitLab Duo](https://about.gitlab.com/gitlab-duo/). If you start typing `Weather getCurrentWeather(const std::string& apiKey, double lat, double lon) {` to complete the function, GitLab Duo will provide the function contents for you, line by line. \n\n![GitLab Duo completing the function contents](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749676998/Blog/Content%20Images/3.get-current-weather-function-completion.png)\n\nHere's what your `getCurrentWeather()` function can look like: \n\n```cpp\n\nWeather getCurrentWeather(const std::string& apiKey, double lat, double lon) {\n   std::string url = \"http://api.openweathermap.org/data/2.5/weather?lat=\" + std::to_string(lat) + \"&lon=\" + std::to_string(lon) + \"&appid=\" + apiKey;\n   std::string response = httpRequest(url);\n   auto json = nlohmann::json::parse(response);\n   Weather weather;\n   if (!json.is_null()) {\n       weather.main = json[\"weather\"][0][\"main\"];\n       weather.description = json[\"weather\"][0][\"description\"];\n       weather.temperature = json[\"main\"][\"temp\"];\n   }\n   return weather;\n}\n```\n\nAnd, finally, we update our `main.cpp` file in the main function to output the current forecast (and converting Kelvin to Celsius for the output):  \n\n```cpp\n   Weather currentWeather = getCurrentWeather(apiKey, lat, lon);\n   if (currentWeather.main.empty()) {\n       std::cerr \u003C\u003C \"Failed to fetch current weather.\" \u003C\u003C std::endl;\n       return 1;\n   }\n\n   std::cout \u003C\u003C \"Current Weather: \" \u003C\u003C currentWeather.main \u003C\u003C \", \" \u003C\u003C currentWeather.description\n       \u003C\u003C \", temperature \" \u003C\u003C currentWeather.temperature - 273.15 \u003C\u003C \" °C\" \u003C\u003C std::endl;\n```\n\nWe can confirm that our new feature is working by building and running the application:  \n\n```shell\ncmake --build build\n./build/air_quality_app \n```\n\nAnd we should see the following output or similar in case the weather is different on the day the code is run :)\n\n```\nAir Quality Index for Zip Code 90210: 2 (Poor)\nCurrent Weather: Clouds, broken clouds, temperature 23.2 °C\n```\n\nWith all new functionality, there should be testing! We can also write a test to check whether the application is fetching and parsing a weather forecast correctly. This test checks that the function returns a list containing the correct number of forecast entries and that each entry has accurate data regarding time and temperature.\n\n```cpp\nTEST_CASE(\"Current Weather functionality\", \"[api]\") {\n   auto weather = getCurrentWeather(\"dummyApiKey\", 40.7128, -74.0060);\n   // Ensure main weather description is not empty\n   REQUIRE_FALSE(weather.main.empty());\n   // Validate that temperature is a reasonable value\n   REQUIRE(weather.temperature > 0); \n}\n```\n\nWe’ll also have to update our `mockHTTPRequest` function in `tests.cpp` to account for this new test. Modify the if-condition with a new else-if branch checking for the `weather` string in the URL:  \n\n```cpp\n// Mock HTTP request function that simulates API responses\nstd::string mockHttpRequest(const std::string &url)\n{\n   if (url.find(\"geo\") != std::string::npos)\n   {\n       // Mock response for geocoding\n       return R\"({\"lat\": 40.7128, \"lon\": -74.0060})\";\n   }\n   else if (url.find(\"air_pollution\") != std::string::npos)\n   {\n       // Mock response for air quality\n       return R\"({\"list\": [{\"main\": {\"aqi\": 2}}]})\";\n   }\n   else if (url.find(\"weather\") != std::string::npos)\n   {\n       // Mock response for current weather\n       return R\"({\n          \"weather\": [{\"main\": \"Clear\", \"description\": \"clear sky\"}],\n          \"main\": {\"temp\": 298.55}\n      })\";\n   }\n   return \"{}\";\n}\n```\n\nAnd verify that our tests are working by rebuilding and running our tests:  \n\n```shell\ncmake --build build \n./build/tests\n```\n\nAll tests should pass, including the new one for Current Weather Functionality. \n\n## Optimize tests.cpp with sections\n\nTo better organize our tests as the project grows and categorize each functionality, we can use Catch2’s `SECTION` macro. The `SECTION` macro allows you to define logically separate test scenarios within a single test case, providing a clean way to test different behaviors or conditions without requiring multiple separate test cases or multiple files. This approach keeps related tests bundled together and also improves test maintainability by allowing shared setup code to be executed repeatedly for each section.\n\nSince some of our functionality is preprocessing data to retrieve information, let’s section our tests as such:\n- preprocessing steps: \n\t- API key validation\n\t- geocoding validation\n-  API data retrieval:\n\t- air pollution retrieval \n\t- forecast retrieval\n\nHere’s what our `tests.cpp` will look like if organized by sections: \n\n```cpp\n#include \"functions.h\"\n#include \u003Ccatch2/catch_test_macros.hpp>\n#include \u003Cstring>\n\n// Mock HTTP request function that simulates API responses\nstd::string mockHttpRequest(const std::string &url)\n{\n   if (url.find(\"geo\") != std::string::npos)\n   {\n       // Mock response for geocoding\n       return R\"({\"lat\": 40.7128, \"lon\": -74.0060})\";\n   }\n   else if (url.find(\"air_pollution\") != std::string::npos)\n   {\n       // Mock response for air quality\n       return R\"({\"list\": [{\"main\": {\"aqi\": 2}}]})\";\n   }\n   else if (url.find(\"weather\") != std::string::npos)\n   {\n       // Mock response for current weather\n       return R\"({\n          \"weather\": [{\"main\": \"Clear\", \"description\": \"clear sky\"}],\n          \"main\": {\"temp\": 298.55}\n      })\";\n   }\n   return \"{}\";\n}\n\n// Overriding the actual httpRequest function with the mockHttpRequest for testing\nstd::string httpRequest(const std::string &url)\n{\n   return mockHttpRequest(url);\n}\n\n// Preprocessing Steps\nTEST_CASE(\"Preprocessing Steps\", \"[preprocessing]\") {\n   SECTION(\"API Key Retrieval\") {\n       // Set the API_KEY environment variable for testing\n       setenv(\"API_KEY\", \"test_key\", 1);\n       // Test if the key is retrieved correctly\n       REQUIRE_FALSE(getApiKey().empty());\n   }\n\n   SECTION(\"Geocode Functionality\") {\n       std::string apiKey = \"test_key\";\n       std::pair\u003Cdouble, double> coordinates = geocodeZipcode(\"90210\", apiKey);\n       // Check latitude\n       REQUIRE(coordinates.first == 40.7128);\n       // Check longitude \n       REQUIRE(coordinates.second == -74.0060);\n   }\n}\n\n// API Data Retrieval\nTEST_CASE(\"API Data Retrieval\", \"[data_retrieval]\") {\n   SECTION(\"Air Quality Functionality\") {\n       std::string apiKey = \"test_key\";\n       double lat = 40.7128;\n       double lon = -74.0060;\n       std::string response = fetchAirQuality(lat, lon, apiKey);\n       // Check the response\n       REQUIRE(response == R\"({\"list\": [{\"main\": {\"aqi\": 2}}]})\");\n   }\n\n   SECTION(\"Current Weather Functionality\") {\n       auto weather = getCurrentWeather(\"dummyApiKey\", 40.7128, -74.0060);\n       // Ensure main weather description is not empty\n       REQUIRE_FALSE(weather.main.empty());\n       // Validate that temperature is a reasonable value\n       REQUIRE(weather.temperature > 0);\n   }\n}\n```\n\nRebuild the code and run the tests again to verify.\n\n```shell\ncmake --build build \n./build/tests\n```\n\n## Next steps\n\nIn this post, we covered how to integrate unit testing into a `C++` project using Catch2 testing framework and GitLab CI/CD and set up basic tests for our reference air quality application project.\n\nTo explore these concepts further, you can check out the [Catch2 documentation](https://github.com/catchorg/Catch2) and [GitLab's Unit test report examples documentation](https://docs.gitlab.com/ee/ci/testing/unit_test_report_examples.html). \n\nFor an advanced async exercise, you could build upon this project by using GitLab Duo to implement a feature that retrieves and analyzes historical air quality data and add code quality checks into the CI/CD pipeline. Happy coding! \n",[827,1198,825,717,9],{"slug":1280,"featured":91,"template":698},"develop-c-unit-testing-with-catch2-junit-and-gitlab-ci","content:en-us:blog:develop-c-unit-testing-with-catch2-junit-and-gitlab-ci.yml","Develop C Unit Testing With Catch2 Junit And Gitlab Ci","en-us/blog/develop-c-unit-testing-with-catch2-junit-and-gitlab-ci.yml","en-us/blog/develop-c-unit-testing-with-catch2-junit-and-gitlab-ci",{"_path":1286,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1287,"content":1293,"config":1300,"_id":1302,"_type":14,"title":1303,"_source":16,"_file":1304,"_stem":1305,"_extension":19},"/en-us/blog/developer-relations-at-gitlab-what-weve-learned-since-our-start",{"title":1288,"description":1289,"ogTitle":1288,"ogDescription":1289,"noIndex":6,"ogImage":1290,"ogUrl":1291,"ogSiteName":686,"ogType":687,"canonicalUrls":1291,"schema":1292},"Developer Relations at GitLab: What we've learned since our start","DevRel is key to success for many tech companies. Find out how GitLab's DevRel program has evolved to stay aligned with the industry and our customers.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749672008/Blog/Hero%20Images/AdobeStock_204527293.jpg","https://about.gitlab.com/blog/developer-relations-at-gitlab-what-weve-learned-since-our-start","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Developer Relations at GitLab: What we've learned since our start\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"John Coghlan\"}],\n        \"datePublished\": \"2024-03-13\",\n      }",{"title":1288,"description":1289,"authors":1294,"heroImage":1290,"date":1295,"body":1296,"category":1297,"tags":1298},[1080],"2024-03-13","Earlier this year, a tweet (are they still called that?) by [Kelsey Hightower](https://twitter.com/kelseyhightower) sparked discussion on social media and internally at GitLab. \n\n![Kelsey Hightower tweet](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749678041/Blog/Content%20Images/Screenshot_2024-03-08_at_8.19.09_AM.png)\n\nAt first, Kelsey's response might seem a bit flippant, but there’s an underlying truth to it: Developer Relations (short: DevRel) – and other business functions – must meet the needs of the business and your customers. However, what your stakeholders and customers need will be different in the future. Therefore, to be successful, you have to iterate to stay aligned with them. \n\nReflecting back on my five years working in Developer Relations (formerly known as Community Relations) at GitLab, our team has continuously evolved to stay aligned with the needs of our customers, our community, and the business. GitLab CEO and founder Sid Sijbrandij explains how North Star Metrics evolve in his blog post on goal-setting for startups: [Artificially constraining your company to one goal creates velocity and creativity](https://opencoreventures.com/blog/2023-06-05-artificially-constrain-one-goal-to-create-creativity-velocity/). He details the shift from attention to active users to revenue to profit. The evolution of DevRel at GitLab in many ways maps to that same journey.\n\n![What is DevRel - image 2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749678041/Blog/Content%20Images/image1.png)\n\n## Early DevRel at GitLab\n\nWhen I joined GitLab in 2018, our team was largely made up of Community Advocates, an Evangelist Program Manager (me), a Code Contributor program manager, and a director. The Community Advocates were tasked with monitoring and engaging with GitLab community members across various online channels but primarily [Hacker News](https://handbook.gitlab.com/handbook/marketing/developer-relations/developer-evangelism/hacker-news/) and Twitter. Answering questions and creating issues based on comments served to increase awareness and attention for GitLab. In addition, users learned that their questions would be answered and feedback was being heard and, frequently, acted on.\n\nAt the same time, the Code Contributor program and Evangelist program were driving growth and interest in GitLab by helping our contributors navigate the contribution process, organizing events and meetups to connect our community, and deepening our relationship with our community champions, also known as [GitLab Heroes](https://about.gitlab.com/community/heroes/). \n\nFor companies in early stages, this is how DevRel often looks. The key tactics in this phase are:\n- use low-cost tools (blogs and social media) to drive attention\n- capitalize on people’s interest to deepen relationships and create advocates and champions\n- smooth the pathways to contribute or discover content\n\n> **Tip:** Direct engagement with your community through social media and online forums drives awareness, builds trust, and increases the quality and volume of feedback on your product. \n\n## Expanding DevRel's reach \n\nNext, we ramped up programs like GitLab for Open Source and GitLab for Education. These programs helped attract to our platform key open source projects and many large academic institutions, both with large numbers of engaged users. More users meant more feedback to help us improve the product and more contributors. \n\nAs attention grew and the breadth and depth of our platform increased, we needed to better enable our customers to leverage the capabilities of GitLab’s DevSecOps Platform. This stage roughly maps to the revenue North Star Metric. To drive greater awareness and adoption, the Community Relations team underwent a critical change.\n\n> **Tip:** When looking to grow your active users, engage with partners who can bring their community to your product or platform. This strategy is often overlooked but can be a big boost to awareness and growth, setting you up for success. \n\n## Deepening the DevRel bench\n\nAs our next move, we formed a team of technical experts, known as Developer Evangelists. This team engaged in more traditional DevRel practices, those that might come to mind when asking yourself “What is DevRel?”. Internally, we referred to this team’s role as the three Cs: \n- Content creation - creating blog posts, technical talks, demos, and other content to enable our customers\n- Community engagement - engaging online and at events with our customers and community\n- Consulting - serving as internal advocates for and experts on the wider GitLab community\n\nHaving technical experts who could connect directly with customers and escalate that feedback internally helped improve the feedback loop between users and product teams. This team also deeply understood GitLab users, which improved the company's ability to enable our customers and community through content.\n\n> **Tip:** Early in your company journey, executives, product managers, and engineers play a vital role in engaging with community. As the number of users grows, you’ll need technical experts on your team who can directly engage with users and ensure customer feedback reaches key stakeholders (executives and product owners).\n\n## Continuously evolving DevRel at GitLab\n\nOver the past year, the team has evolved again.\n\n- A new vice president joined our team and has helped us become more strategic and better aligned cross-functionally.\n\n- A Contributor Success team was established to better engage and align with our customers around contributions to GitLab. Evolving from a one-person function to a full-fledged team of engineers with deep experience in open source (including multiple past contributors to GitLab), this team continuously improves the contribution experience and engages directly with customers who wish to contribute.\n\n- We updated our team name and many of our team members’ job titles to align with industry standards.\n\n- And we’ve all ramped up quite a bit on AI, perhaps you’ve heard of [GitLab Duo](https://about.gitlab.com/gitlab-duo/)? \n\nAs GitLab continues to mature as a public company, the team will continue to evolve. Through these changes, we will stay focused on increasing the efficiency and impact of our efforts for our customers, our product, and our team.\n\n## Gaining - and maintaining - executive buy-in\n\nExecutive buy-in is essential for DevRel. Look at the companies with the largest, most engaged communities and you will find that those companies also have the most active, engaged, and often highly respected founders and CEOs. This is certainly true with GitLab. \n\nGitLab’s engagement with our community began before we were even a company when Dmitriy Zaporozhets (DZ) started the open source GitLab project with [this commit](https://gitlab.com/gitlab-org/gitlab-foss/commit/9ba1224867665844b117fa037e1465bb706b3685). The engagement continued when Sid [launched GitLab on Hacker News](https://news.ycombinator.com/item?id=4428278).\n\nThe importance of community in GitLab’s success cannot be overstated, and while we’ve grown to heights that few companies reach, contributions from our customers and community remain central in [our strategy](https://handbook.gitlab.com/handbook/company/strategy/#dual-flywheels). Because of this, team members, from the highest levels of GitLab and throughout our organization, remain in active communication with our customers via issues and social forums, working hard at all times to help them succeed. Transparency is key here. Documenting our DevRel strategies in the [public GitLab handbook](https://handbook.gitlab.com/handbook/marketing/developer-relations/) enables everyone to contribute.\n\n> **Tip:** Executive support is critical when building a community.\n\n## So what is DevRel?\n\nI want to go back to the initial question that sparked this blog: What is DevRel? \n\nI’ll leave you with a quote from Emilio Salvador, vice president of Developer Relations at GitLab, which was recently merged to [our handbook page](https://handbook.gitlab.com/handbook/marketing/developer-relations): \n\n\u003Ci>\"Developer Relations (short: DevRel) operates at the intersection of technology, community, and advocacy, serving as the voice and ears of GitLab in the wider tech world. Their core mission revolves around nurturing and sustaining a vibrant, engaged community of developers, contributors, and users. This involves a multifaceted approach that includes creating educational content, organizing events and workshops, developing programs, and providing platforms for knowledge exchange and collaboration. The team not only focuses on promoting GitLab’s features and capabilities but also actively listens to and incorporates feedback from the community to inform product development and improvements.\"\u003C/i>\n\nThat’s what it is today, but if the history of DevRel at GitLab is any indication, I expect that we’ll continue to iterate going forward. \n\n> [Join our Discord community](https://discord.gg/gitlab) to continue the conversation.\n","culture",[1299,9,1038],"DevOps",{"slug":1301,"featured":91,"template":698},"developer-relations-at-gitlab-what-weve-learned-since-our-start","content:en-us:blog:developer-relations-at-gitlab-what-weve-learned-since-our-start.yml","Developer Relations At Gitlab What Weve Learned Since Our Start","en-us/blog/developer-relations-at-gitlab-what-weve-learned-since-our-start.yml","en-us/blog/developer-relations-at-gitlab-what-weve-learned-since-our-start",{"_path":1307,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1308,"content":1314,"config":1322,"_id":1324,"_type":14,"title":1325,"_source":16,"_file":1326,"_stem":1327,"_extension":19},"/en-us/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd",{"title":1309,"description":1310,"ogTitle":1309,"ogDescription":1310,"noIndex":6,"ogImage":1311,"ogUrl":1312,"ogSiteName":686,"ogType":687,"canonicalUrls":1312,"schema":1313},"GitLab Duo: AI-powered CI/CD pipeline root cause analysis","Discover how we've infused Root Cause Analysis with AI to help remedy broken CI/CD pipelines, including example scenarios and take-away exercises.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097321/Blog/Hero%20Images/Blog/Hero%20Images/blog-hero-banner-1-0178-820x470-fy25_7JlF3WlEkswGQbcTe8DOTB_1750097321081.png","https://about.gitlab.com/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Developing GitLab Duo: Blending AI and Root Cause Analysis to fix CI/CD pipelines\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Rutvik Shah\"},{\"@type\":\"Person\",\"name\":\"Michael Friedrich\"}],\n        \"datePublished\": \"2024-06-06\",\n      }",{"title":1315,"description":1310,"authors":1316,"heroImage":1311,"date":1319,"body":1320,"category":781,"tags":1321},"Developing GitLab Duo: Blending AI and Root Cause Analysis to fix CI/CD pipelines",[1317,1318],"Rutvik Shah","Michael Friedrich","2024-06-06","___Generative AI marks a monumental shift in the software development industry, making it easier to develop, secure, and operate software. Our new blog series, written by our product and engineering teams, gives you an inside look at how we create, test, and deploy the AI features you need integrated throughout the enterprise. Get to know new capabilities within GitLab Duo and how they will help DevSecOps teams deliver better results for customers.___\n\nHave you ever encountered a broken [CI/CD](https://about.gitlab.com/topics/ci-cd/benefits-continuous-integration/) pipeline and had to halt your DevSecOps workflow, or even delay software deployment, as you try to figure out the root cause? Traditionally, when something goes wrong in the process of creating software, developers have to troubleshoot, dig through log files, and often do a lot of trial and error development. [GitLab Duo Root Cause Analysis](https://about.gitlab.com/gitlab-duo/), part of our suite of AI-powered features, removes the guesswork by determining the root cause for a failed CI/CD pipeline. In this article, you'll learn what Root Cause Analysis is and how to apply the AI-powered GitLab Duo feature to your DevSecOps workflow.\n\n> Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Watch today!](https://about.gitlab.com/seventeen/)\n\n### What is Root Cause Analysis?\n\nGitLab Duo Root Cause Analysis is an AI-powered feature that assists you in determining a root cause and suggesting a fix for a CI/CD job log failure by analyzing the logs.\n\nWhile Root Cause Analysis is often seen in product incident management, its workflows and debugging practices can be found in any DevSecOps workflow. Ops teams, administrators, and platform engineers are challenged by infrastructure-as-code (IaC) deployment errors, Kubernetes and GitOps problems, and long stack traces while investigating pipeline failures.\n\nGitLab Duo Root Cause Analysis keeps everyone in the same interface and uses AI-powered help to summarize, analyze, and propose fixes so that organizations can release secure software faster.\n\nA pipeline can encounter failures for a variety of reasons, including syntax errors in the code, missing dependencies that the pipeline relies on, test failures during the build process, Kubernetes and IaC deployment timeouts, and numerous other potential issues. When such failures occur, it becomes the responsibility of everyone to meticulously review the logs generated by the pipeline. This job log review process involves scrutinizing the detailed output to identify the specific errors and pinpoint the root cause of the pipeline failure. For example, the following pipeline has multiple job failures that need to be investigated and fixed.\n\n![Image depicting multiple job failures](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097332/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750097332601.png)\n\nThe duration required to fix these failures can vary significantly and is largely influenced by several factors such as:\n- the developer's familiarity with the project\n- their level of experience in dealing with similar issues\n- their overall skill level in troubleshooting and problem-solving within the context of the pipeline.\n\nManual analysis can be exceedingly challenging and time-consuming, given that log data consists of application logs and system messages with a wide variety of potential sources of failures. A typical pipeline fix can consist of several iterations and context switching. The complexity and the unstructured nature of the logs is a perfect fit for speeding up the task using generative AI.  Using AI can reduce the time to identify and fix a pipeline error significantly and also lower the barrier of expertise that would be needed to fix a pipeline such as the above.\n\nWatch GitLab Duo Root Cause Analysis in action:\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n\n \u003Ciframe src=\"https://www.youtube.com/embed/sTpSLwX5DIs?si=J6-0Bf6PtYjrHX1K\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n### How does Root Cause Analysis work?\n\n[Root Cause Analysis](https://docs.gitlab.com/ee/user/ai_experiments.html#root-cause-analysis) works by forwarding a portion of the CI/CD job log to the [GitLab AI Gateway](https://docs.gitlab.com/ee/architecture/blueprints/ai_gateway/). GitLab ensures that the portion sent will fit inside the large language model (LLM) token limits alongside a prompt that has been pre-crafted to provide insights into why the job might have failed. The prompt also instructs the LLM to provide an example of how a user might fix a broken job.\n\nHere are two example scenarios where Root Cause Analysis can provide assistance.\n\n#### 1. Analyze a Python dependency error\n\nA Python application can import package modules with functionality that is not provided in the standard library. The project [Challenge - Root Cause Analysis - Python Config](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/root-cause-analysis/challenge-root-cause-analysis-python-config) implements an application that parses configuration and initializes an SQLite database, which both work well without any dependencies. It uses best practices in CI/CD with a Python environment and caching. The latest feature implementation adds a Redis caching client, and now the CI/CD build is failing for some reason. \n\nBy using Root Cause Analysis, you can immediately learn that the `ModuleNotFoundError` text means that the module is actually not installed in the Python environment. GitLab Duo also suggests an example fix: Installing the Redis module through the PIP package manager. \n\n![Image depicting 'modulenotfounderror' and GL Duo suggested resolution](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097332/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750097332602.png)\n\nThe failing pipeline can be viewed [here](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/root-cause-analysis/challenge-root-cause-analysis-python-config/-/jobs/6992716398). \n\nThe Root Cause Analysis prompt provides a summary of the problem, which seems to be a problem with a missing `redis` module. Let's try to fix the problem by installing the `redis` module. You can either call `pip install redis` in the CI/CD job `script` section, or use a more sophisticated approach with the `requirements.txt` file. The latter is useful for a single source of truth for dependencies installed in the development environment and CI/CD pipelines.\n\n```yaml\ntest:\n  extends: [.python-req]\n  stage: test \n  before_script:\n    # [🦊] hint: Root cause analysis.\n    # Solution 1: Install redis using pip\n    - pip install redis\n    # Solution 2: Add redis to requirements.txt, use pip\n    - pip install -r requirements.txt \n\n  script:\n    - python src/main.py\n```\n\nAfter fixing the missing Python dependency, the CI/CD job fails again. Use Root Cause Analysis again to learn that no Redis service is running in the job. Switch to using GitLab Duo Chat and use the prompt `How to start a Redis service in CI/CD` to learn how to configure the `services` attribute in the CI/CD job.\n\n![Depicts the prompt for how to start a Redis service](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097333/Blog/Content%20Images/Blog/Content%20Images/image6_aHR0cHM6_1750097332602.png)\n\nModify the `.gitlab-ci.yml` with the `test` job, and specify the `redis` service.\n\n```yaml\ntest:\n  extends: [.python-req]\n  stage: test \n  before_script:\n    # [🦊] hint: Root cause analysis.\n    # Solution 1: Install redis using pip\n    - pip install redis\n    # Solution 2: Add redis to requirements.txt, use pip\n    - pip install -r requirements.txt \n\n  script:\n    - python src/main.py\n\n  # Solution 3 - Running Redis\n  services:\n    - redis\n```\n\nRunning the Redis server allows you to successfully execute the Python application, and print its output into the CI/CD job log.\n\n![output of Python application](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097332/Blog/Content%20Images/Blog/Content%20Images/image4_aHR0cHM6_1750097332603.png)\n\nThe solution is provided in the [solution/ directory](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/root-cause-analysis/challenge-root-cause-analysis-python-config/-/tree/main/solution?ref_type=heads).\n\n**Tip:** You can also ask [GitLab Duo Chat](https://docs.gitlab.com/ee/user/gitlab_duo_chat.html) to follow up on potential future problems:\n\n```markdown\nHow to lint Python code? Which tools are recommended for CI/CD.\nHow to pin a package version in Python requirements file?\t\nWhat are possible ways that this exception stacktrace is triggered in the future?\nAre there ways to prevent the application from failing?\n``` \n\nThe next example is more advanced and includes multiple failures. \n\n#### 2. Analyze missing Go runtime\n\nCI/CD jobs can be executed in containers, spawned from the contributed `image` attribute. If the container does not provide a programming language runtime, the executed `script` sections referencing the `go` binary fail. For example, the error message `/bin/sh: eval: line 149: go: not found` needs to be understood and fixed. \n\nIf the `go` command is not found in the container's runtime context, this can have multiple reasons:\n\n1. The job uses a minimal container image, for example `alpine`, and the Go language runtime was not installed.\n1. The job uses the wrong default container image, for example, specified on top of the CI/CD configuration, or using the `default` keyword.\n1. The job does not use a container image but the shell executor. The host operating system does not have the Go language runtime installed, or it is otherwise broken/not configured.\n\nThe project [Challenge - Root Cause Analysis - Go GitLab Release Fetcher](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/root-cause-analysis/challenge-root-cause-analysis-go-gitlab-release-fetcher) provides an exercise challenge to analyze and fix CI/CD problems with a GitLab release fetcher application, written in Go. The `build` and `docker-build` CI/CD jobs are failing. Fixing the problem requires different scopes: Understanding why the Go runtime is not installed, and learning about the `Dockerfile` syntax. \n\n![Screenshot showing Change Docker Label job failed](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097332/Blog/Content%20Images/Blog/Content%20Images/image5_aHR0cHM6_1750097332603.png)\n\nThe [`solution/` directory](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/root-cause-analysis/challenge-root-cause-analysis-go-gitlab-release-fetcher) provides two possible solutions after Root Cause Analysis. \n\n## Practice using Root Cause Analysis\n\nHere are some scenarios to use to practice using Root Cause Analysis.\n\n- When you are running into Kubernetes deployment errors or timeouts. \n\n- With OpenTofu or Terraform IaC pipelines failing to provision your cloud resources.\n\n- When the Ansible playbook fails with a cryptic permission error in CI/CD.\n\n- When the Java stack trace is 10 pages long.\n\n- With a shell script highlighting an execution error.\n\n- When a Perl script fails in a single line, which is the only line in the script.\n\n- When the CI/CD job times out and it is unclear which section would cause this.\n\n- When a network connection timeout is reached, and you think it cannot be DNS.\n\n### What is next for GitLab Duo Root Cause Analysis?\n\nWe want to help our users to get their pipelines back to passing in fewer iterations. The Root Cause Analysis will open and show the response in GitLab Duo Chat, our AI assistant. Users can build on the recommendation to generate a more precise fix by asking specific questions (e.g., programming language-specific fixes) or asking for alternative fixes based on the root cause.\n\nFor example, here is the Root Cause Analysis for a failing job:\n\n![Root Cause Analysis response](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097332/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750097332603.png)\n\nUsers can ask follow-up questions that build upon the AI-generated response.\n\n- I do not want to create my own Docker image. Please explain different ways to fix the problem.\n\n- I don't have access to the Docker image creation. It seems that the Go binary is missing. Are there alternative images you can suggest?\n\nGitLab also will be running quality benchmarks for the generated responses and shipping usability improvements.\n\nPlease see our [Root Cause Analysis GA epic](https://gitlab.com/groups/gitlab-org/-/epics/13080) for more details. We would also love your feedback on the feature. Please leave a comment on our [Root Cause Analysis feedback issue](https://gitlab.com/groups/gitlab-org/-/epics/13872).\n\n## Get started with Root Cause Analysis\n\nPlease see our [documentation](https://docs.gitlab.com/ee/user/ai_experiments.html#root-cause-analysis) on how to enable the feature available to our GitLab Ultimate customers. Also, GitLab Duo Root Cause Analysis will soon be coming to GitLab self-managed and GitLab Dedicated.\n\nNot a GitLab Ultimate customer? Start [a free trial](https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/blog&glm_content=default-saas-trial) today. \n\n## Read more of our \"Developing GitLab Duo\" series\n\n- [Developing GitLab Duo: How we validate and test AI models at scale](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/)\n\n- [Developing GitLab Duo: AI Impact analytics dashboard measures the ROI of AI](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/)\n\n- [Developing GitLab Duo: How we are dogfooding our AI features](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/)\n\n- [Developing GitLab Duo: Secure and thoroughly test AI-generated code](https://about.gitlab.com/blog/how-gitlab-duo-helps-secure-and-thoroughly-test-ai-generated-code/)",[717,827,9,496,719],{"slug":1323,"featured":91,"template":698},"developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd","content:en-us:blog:developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd.yml","Developing Gitlab Duo Blending Ai And Root Cause Analysis To Fix Ci Cd","en-us/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd.yml","en-us/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd",{"_path":1329,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1330,"content":1335,"config":1341,"_id":1343,"_type":14,"title":1344,"_source":16,"_file":1345,"_stem":1346,"_extension":19},"/en-us/blog/developing-gitlab-duo-how-we-validate-and-test-ai-models-at-scale",{"title":1331,"description":1332,"ogTitle":1331,"ogDescription":1332,"noIndex":6,"ogImage":708,"ogUrl":1333,"ogSiteName":686,"ogType":687,"canonicalUrls":1333,"schema":1334},"Developing GitLab Duo: How we validate and test AI models at scale","Our blog series debuts with a behind-the-scenes look at how we evaluate LLMs, match them to use cases, and fine-tune them to produce better responses for users.","https://about.gitlab.com/blog/developing-gitlab-duo-how-we-validate-and-test-ai-models-at-scale","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Developing GitLab Duo: How we validate and test AI models at scale\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Susie Bitters\"}],\n        \"datePublished\": \"2024-05-09\",\n      }",{"title":1331,"description":1332,"authors":1336,"heroImage":708,"date":1338,"body":1339,"category":781,"tags":1340},[1337],"Susie Bitters","2024-05-09","**_Generative AI marks a monumental shift in the software development industry, making it easier to develop, secure, and operate software. Our new blog series, written by our product and engineering teams, gives you an inside look at how we create, test, and deploy the AI features you need integrated throughout the enterprise. Get to know new capabilities within GitLab Duo and how they will help DevSecOps teams deliver better results for customers._**\n\nGitLab values the trust our customers place in us. Part of maintaining that trust is transparency in how we build, evaluate, and ensure the high-quality functionality of our [GitLab Duo](https://about.gitlab.com/gitlab-duo/) AI features. GitLab Duo features are powered by a diverse set of models, which allows us to support a broad set of use cases and gives our customers flexibility. GitLab is not tied to a single model provider by design. We currently use foundation models from [Google](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/blob/main/ai_gateway/models/vertex_text.py?ref_type=heads#L86) and [Anthropic](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/blob/main/ai_gateway/models/anthropic.py?ref_type=heads#L62). However, we continuously assess what models are the right matches for GitLab Duo’s use cases. In this article, we give you an inside look at our AI model validation process.\n\n> Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Watch today!](https://about.gitlab.com/seventeen/)\n\n## Understanding LLMs\n\nLarge language models (LLMs) are generative AI models that power many AI features across the platform. Trained on vast datasets, LLMs predict the next word in a sequence based on preceding context. Given an input prompt, they generate human-like text by sampling from the probability distribution of words conditioned on the prompt.\n\nLLMs enable intelligent code suggestions, conversational chatbots, code explanations, vulnerability analysis, and more. Their ability to produce diverse outputs for a given prompt makes standardized quality evaluation challenging. LLMs can be optimized for different characteristics, which is why there are so many AI models actively being developed.\n\n## Testing at scale\n\nUnlike traditional software systems where inputs and outputs can be more easily defined and tested, LLMs produce outputs that are often nuanced, diverse, and context-dependent. Testing these models requires comprehensive strategies that account for subjective and variable interpretations of quality, as well as the stochastic nature of their outputs. We, therefore, cannot judge the quality of an LLM’s output in an individual or anecdotal fashion; instead, we need to be able to examine the overall pattern of an LLM's behavior. To get a sense of those patterns, we need to test at scale. Testing at scale refers to the process of evaluating the performance, reliability, and robustness of a system or application across a large and diverse array of datasets and use cases. Our [Centralized Evaluation Framework (CEF)](https://about.gitlab.com/direction/ai-powered/ai_framework/ai_evaluation/) utilizes thousands of prompts tied to dozens of use cases to allow us to identify significant patterns and assess the overall behavior of our foundational LLMs and the GitLab Duo features in which they are integrated.\n\nTesting at scale helps us:\n\n- **Ensure quality:** Testing at scale enables us to assess the quality and reliability of these models across a wide range of scenarios and inputs. By validating the outputs of these models at scale, we can start to identify patterns and mitigate potential issues such as systematic biases, anomalies, and inaccuracies. \n- **Optimize performance:** Scaling up testing efforts allows GitLab to evaluate the performance and efficiency of LLMs under real-world conditions. This includes assessing factors such as output quality, latency, and cost to optimize the deployment and operation of these models in GitLab Duo features.\n- **Mitigate risk:** Testing LLMs at scale helps mitigate the risks associated with deploying LLMs in critical applications. By conducting thorough testing across diverse datasets and use cases, we can identify and address potential failure modes, security vulnerabilities, and ethical concerns before they impact our customers.\n\nTesting LLMs at scale is imperative for ensuring their reliability and robustness for deployment within the GitLab platform. By investing in comprehensive testing strategies that encompass diverse datasets, use cases, and scenarios, GitLab is working to unlock the full potential of AI-powered workflows while mitigating potential risks.\n\n### How we test at scale\n\nThese are the steps we take to test LLMs at scale.\n\n#### Step 1: Create a prompt library as a proxy for production\nWhile other companies view and use customer data to train their AI features, GitLab currently does not.  As a result, we needed to develop a comprehensive prompt library that is a proxy for both the scale and activity of production.\n\nThis prompt library is composed of questions and answers. The questions represent the kinds of queries or inputs that we would expect to see in production, while the answers represent a ground truth of what our ideal answer would be. This ground truth answer could also be mentally framed as a target answer. Both the question and the answer may be human generated, but are not necessarily so. These question/answer pairs give us a basis for comparison and a reference frame that allow us to tease out differences between models and features. When multiple models are asked the same question and generate different responses, we can use our ground truth answer to determine which model has provided an answer that is most closely aligned to our target and score them accordingly.\n\nAgain, a key element of a comprehensive prompt library is ensuring that it is representative of the inputs that we expect to see in production. We want to know how well foundational models fit to our specific use case, and how well our features are performing. There are numerous benchmark prompt datasets, but those datasets may not be reflective of the use cases that we see for features at GitLab. Our prompt library is designed to be specific to GitLab features and use cases.\n\n#### Step 2: Baseline model performance\n\nOnce we have crafted a prompt library that accurately reflects production activity, we feed those questions into [various models](https://about.gitlab.com/direction/ai-powered/ai_framework/ai_evaluation/foundation_models/) to test how well they serve our customer’s needs. We compare each response to our ground truth and provide it a ranking based on a series of metrics including: [Cosine Similarity Score](https://about.gitlab.com/direction/ai-powered/ai_framework/ai_evaluation/metrics/#similarity-scores), [Cross Similarity Score](https://about.gitlab.com/direction/ai-powered/ai_framework/ai_evaluation/metrics/#cross-similarity-score),  [LLM Judge](https://about.gitlab.com/direction/ai-powered/ai_framework/ai_evaluation/metrics/#llm-judge), and [Consensus Filtering with an LLM Judge](https://about.gitlab.com/direction/ai-powered/ai_framework/ai_evaluation/metrics/#consensus-filtering-with-llm-judge). This first iteration provides us a baseline for how well each model is performing, and guides our selection of a foundational model for our features. For brevity, we won’t go into the details here, but we encourage you to [learn more about more about the metrics here](https://about.gitlab.com/direction/ai-powered/ai_framework/ai_evaluation/metrics/). It is important to note this isn’t a solved problem; the wider AI industry is actively researching and developing new techniques. GitLab’s model validation team keeps a pulse on the industry and is continuously iterating on how we measure and score the LLMs GitLab Duo uses.  \n\n#### Step 3: Feature development\n\nNow that we have a baseline for our selected model's performance, we can start developing our features with confidence. While prompt engineering gets a lot of buzz, focusing entirely on changing the behavior of a model via prompting (or any other technique) without validation means that you are operating in the dark and very possibly overfitting your prompting. You may solve one problem, but be causing a dozen more. You would never know. Creating a baseline for a model's performance allows us to track how we are changing behavior over time for all our necessary use cases. At GitLab, we re-validate the performance of our features on a daily basis during active development to help ensure that all changes improve the overall functionality.\n\n#### Step 4: Iterate, iterate, iterate\n\nHere is how our experimental iterations work. Each cycle, we examine the scores from our tests at scale to identify patterns:\n\n- What are the commonalities across our weakest areas?\n- Is our feature performing poorly based on a specific metric or on a certain use case?\n- Do we see consistent errors popping up in response to a certain kind of question?\n\nOnly when we test at scale do these kinds of patterns begin to emerge and allow us to focus our experiments. Based on these patterns, we propose a variety of experiments or approaches to try to improve performance in a specific area and on a specific metric.\n\nHowever, testing at scale is both expensive and time-consuming. To enable faster and less expensive iteration, we craft a smaller scale dataset to act as a mini-proxy. The focused subset will be weighted to include question/answer pairs that we know we want to improve upon, and the broader subset will also include sampling of all the other use cases and scores to ensure that our changes aren't adversely affecting the feature broadly. Make your change and run it against the focused subset of data. How does the new response compare to the baseline? How does it compare to the ground truth?\n\nOnce we have found a prompt that addresses the specific use case we are working on with the focused subset, we validate that prompt against a broader subset of data to help ensure that it won’t adversely affect other areas of the feature. Only when we believe that the new prompt improves our performance in our target area through validation metrics AND doesn’t degrade performance elsewhere, do we push that change to production.\n\nThe entire Centralized Evaluation Framework is then run against the new prompt and we validate that it has increased the performance of the entire feature against the baseline from the day before. In this way, GitLab is constantly iterating to help ensure that you are getting the latest and greatest performance of AI-powered features across the GitLab ecosystem. This allows us to ensure that we keep working faster, together.\n\n### Making GitLab Duo even better\n\nHopefully this gives you insight into how we’re responsibly developing GitLab Duo features. This process has been developed as we’ve brought [GitLab Duo Code Suggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions/) and [GitLab Duo Chat](https://docs.gitlab.com/ee/user/gitlab_duo_chat.html) to general availability. We’ve also integrated this validation process into our development process as we iterate on GitLab Duo features. It’s a lot of trial and error, and many times fixing one thing breaks three others. But we have data-driven insights into those impacts, which helps us ensure that GitLab Duo is always getting better.\n\n> Start a [free trial of GitLab Duo](https://about.gitlab.com/gitlab-duo/#free-trial) today!\n\n ## Resources\n - [GitLab AI Transparency Center](https://about.gitlab.com/ai-transparency-center/)\n - [GitLab's AI Ethics Principles for Product Development](https://handbook.gitlab.com/handbook/legal/ethics-compliance-program/ai-ethics-principles/)\n - [GitLab AI-powered Direction page](https://about.gitlab.com/direction/ai-powered/)\n\n\u003Cfigure class=video_container>\n\u003Ciframe width=560 height=315 src=\"https://www.youtube-nocookie.com/embed/LifJdU3Qagw?si=A4kl6d32wPYC4168\" title=\"YouTube video player\" frameborder=0 allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\">\u003C/iframe>\n\u003C/figure>\n\n## Read more of the \"Developing GitLab Duo\" series\n\n- [Developing GitLab Duo: AI Impact analytics dashboard measures the ROI of AI](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/)\n- [Developing GitLab Duo: How we are dogfooding our AI features](https://about.gitlab.com/blog/developing-gitlab-duo-how-we-are-dogfooding-our-ai-features/) \n- [Developing GitLab Duo: Secure and thoroughly test AI-generated code](https://about.gitlab.com/blog/how-gitlab-duo-helps-secure-and-thoroughly-test-ai-generated-code/)\n- [Developing GitLab Duo: Blending AI and Root Cause Analysis to fix CI/CD pipelines](https://about.gitlab.com/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd/)",[717,9,496,719,1038],{"slug":1342,"featured":91,"template":698},"developing-gitlab-duo-how-we-validate-and-test-ai-models-at-scale","content:en-us:blog:developing-gitlab-duo-how-we-validate-and-test-ai-models-at-scale.yml","Developing Gitlab Duo How We Validate And Test Ai Models At Scale","en-us/blog/developing-gitlab-duo-how-we-validate-and-test-ai-models-at-scale.yml","en-us/blog/developing-gitlab-duo-how-we-validate-and-test-ai-models-at-scale",{"_path":1348,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1349,"content":1354,"config":1360,"_id":1362,"_type":14,"title":1363,"_source":16,"_file":1364,"_stem":1365,"_extension":19},"/en-us/blog/developing-gitlab-duo-series",{"title":1350,"description":1351,"ogTitle":1350,"ogDescription":1351,"noIndex":6,"ogImage":708,"ogUrl":1352,"ogSiteName":686,"ogType":687,"canonicalUrls":1352,"schema":1353},"Developing GitLab Duo series","Our unique blog series, written by our Product and Engineering teams, takes you behind the scenes of our AI innovation and guides you through our newest AI features powering your DevSecOps workflow.","https://about.gitlab.com/blog/developing-gitlab-duo-series","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Developing GitLab Duo series\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"GitLab Team\"}],\n        \"datePublished\": \"2024-06-03\",\n      }",{"title":1350,"description":1351,"authors":1355,"heroImage":708,"date":1357,"body":1358,"category":781,"tags":1359},[1356],"GitLab Team","2024-06-03","Generative AI marks a monumental shift in the software development industry, making it easier to develop, secure, and operate software. Our blog series, written by our product and engineering teams, gives you an inside look at how we create, test, and deploy the AI features you need integrated throughout the enterprise. Get to know new capabilities within GitLab Duo and how they will help DevSecOps teams deliver better results for customers.\n\n> Live demo! Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Register today](https://about.gitlab.com/seventeen/)!\n\n## 1. [How we validate and test AI models at scale](https://about.gitlab.com/blog/developing-gitlab-duo-how-we-validate-and-test-ai-models-at-scale/)\n\n- Our blog series debuts with a behind-the-scenes look at how we evaluate LLMs, match them to use cases, and fine-tune them to produce better responses for users.\n\n## 2. [AI Impact analytics dashboard measures the ROI of AI](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/)\n\n- We spotlight a new feature that provides detailed metrics, such as the Code Suggestions Usage Rate, to help understand the effectiveness of AI investments.\n\n## 3. [How we are dogfooding our AI features](https://about.gitlab.com/blog/developing-gitlab-duo-how-we-are-dogfooding-our-ai-features/)\n\n- We share real-world examples of how we integrate AI throughout our software development lifecycle and how we use metrics to gauge their success.\n\n## 4. [Secure and thoroughly test AI-generated code](https://about.gitlab.com/blog/how-gitlab-duo-helps-secure-and-thoroughly-test-ai-generated-code/)\n\n- Learn step-by-step how to enhance AI-generated code reliability and security using GitLab Duo and GitLab Pages (includes code samples and prompts).\n\n## 5. [Blending AI and Root Cause Analysis to fix CI/CD pipelines](https://about.gitlab.com/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd/)\n\n- Discover how we've infused Root Cause Analysis with AI to help remedy broken CI/CD pipelines, including example scenarios and take-away exercises.\n\n## 6. [Developing GitLab Duo: A roundup of recent Chat enhancements](https://about.gitlab.com/blog/developing-gitlab-duo-a-roundup-of-recent-chat-enhancements)\n- Discover the latest improvements to GitLab Duo Chat, including prompt cancellation and architectural upgrades. Learn how these updates streamline workflows and boost productivity.\n\n> Learn more about [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our AI-powered suite of features for your DevSecOps workflow. Then start [a free trial of GitLab Duo](https://about.gitlab.com/gitlab-duo/#free-trial) to get the incredible benefits in your own organization! \n\n##  7. [Developing GitLab Duo: Use AI to remediate security vulnerabilities](https://about.gitlab.com/blog/developing-gitlab-duo-use-ai-to-remediate-security-vulnerabilities)\nThis tutorial shows how GitLab Duo Vulnerability Explanation and GitLab Duo Vulnerability Resolution, along with our other AI-powered features, can help to address vulnerabilities quickly.",[717,719,9,496],{"slug":1361,"featured":6,"template":698},"developing-gitlab-duo-series","content:en-us:blog:developing-gitlab-duo-series.yml","Developing Gitlab Duo Series","en-us/blog/developing-gitlab-duo-series.yml","en-us/blog/developing-gitlab-duo-series",{"_path":1367,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1368,"content":1373,"config":1378,"_id":1380,"_type":14,"title":1381,"_source":16,"_file":1382,"_stem":1383,"_extension":19},"/en-us/blog/devsecops-platforms-give-smbs-security-muscle",{"title":1369,"description":1370,"ogTitle":1369,"ogDescription":1370,"noIndex":6,"ogImage":794,"ogUrl":1371,"ogSiteName":686,"ogType":687,"canonicalUrls":1371,"schema":1372},"DevSecOps platforms give SMBs security muscle","A single platform enables teams to build, test, and deploy secure software with fewer resources.","https://about.gitlab.com/blog/devsecops-platforms-give-smbs-security-muscle","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"DevSecOps platforms give SMBs security muscle\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sharon Gaudin\"}],\n        \"datePublished\": \"2023-01-10\",\n      }",{"title":1369,"description":1370,"authors":1374,"heroImage":794,"date":1375,"body":1376,"category":10,"tags":1377},[756],"2023-01-10","\nDevOps professionals with both security training and experience come at a high price and can be hard to find. That makes it especially difficult for startups and small and medium-sized businesses (SMBs), which generally don’t have deep pockets, to get the security professionals they need.\n\nSmaller businesses often end up with no security team, so they have to hire consultants. Even worse, they might end up having little to no security help at all, which will cause problems for their customers as well as their own business.\n\nOne efficient [way to deal with that](/blog/6-ways-smbs-can-leverage-the-power-of-a-devops-platform/) is to adopt a DevSecOps platform, which enables organizations to build, test, and deploy secure software with fewer hands and [expenses](/blog/how-smbs-can-save-with-gitlabs-devops-platform/).\n\n“Someone in an SMB likely doesn’t have enough expertise, or even enough people, in-house to handle every part of DevOps, so they end up having to hire a contractor or consultant to take on things like security and monitoring, and that strains their budget,” says [Fatima Sarah Khalid](https://gitlab.com/sugaroverflow), a developer evangelist at GitLab. “By adopting the GitLab DevSecOps Platform, they can more easily handle this work, despite limited resources.”\n \n## Four benefits for SMBs\n\nSo how does a complete DevSecOps platform add security muscle to a small business? \n\n### 1. Finding vulnerabilities early\n \nWith a single, end-to-end platform, [security is integrated throughout](/stages-devops-lifecycle/secure/), and not just bolted on as an afterthought. With capabilities like dynamic and static application security testing, vulnerability management, and dependency and container scanning, developers can find vulnerabilities earlier in the process when they often can be more easily and quickly fixed. By shifting security left this way, teams can perform threat and vulnerability analysis as developers create the code - not when it’s about to be deployed. Shifting security left also creates more secure software, and decreases the time it would have taken to track down a problem created much earlier in the process.\n \n### 2. Easing work with automation\n \nAutomation, which is built into a single DevSecOps platform, is critical because it brings consistency and repeatability to the entire software lifecycle, reducing the potential for human error and minimizing the introduction of bugs and risks. And that enables SMBs to produce more secure software for their own organizations, as well as for their customers.\n \nAnother major advantage of automation is that it minimizes the need for a lot of extra hands-on and time-consuming work, like code reviews and testing. Startups and small businesses, by nature, have smaller DevOps teams. They might even have an IT team of one or two people, who do everything from building software to serving as the help desk. Saving them from having to do repetitive manual work gives them back precious time they can spend on more innovative and productive jobs.\n \nAll of that automated testing is automatically logged and documented, helping organizations create easily searchable and useful best practices that will help speed future software builds.\n \n### 3. Ensuring compliance\n \nSMBs and companies just getting off the ground don’t want to get tripped up by tricky and costly compliance issues. Luckily, the same end-to-end platform enables teams to verify the compliance of their code without leaving their workflow. In GitLab, for example, compliance confirmation lives within the platform and is automated. Developers don't have to context-switch among different point solutions, boosting their productivity and efficiency. Automating compliance also removes one more task from [developers’ already busy schedules](/blog/ease-pressure-on-smb-developers-with-a-devops-platform/).\n \n### 4. Establishing security imperatives\n \nA DevSecOps platform gives SMBs speed and efficiency, without requiring them to string together various security tools or hire security consultants. With a platform, because security practices and automation are integrated from the very start, an SMB’s DevOps environment has a solid security foundation. One solution. One answer to security needs.\n\n## Meeting the security need\n \nIn today’s environment, security and compliance are business imperatives. There’s no getting around it.\n\nSo having a strategic, end-to-end platform approach, where security and compliance are embedded from planning to production, provides efficiency and value unmatched by traditional, third-party application security vendors. Companies that may be using DevOps but are only tacking together different tools simply aren’t getting the security advantages that come from a single DevSecOps application.\n\nStartups and SMBs have a steep hill to climb just to survive. Between March 2020 and March 2021, 1 million small businesses opened in the U.S., but 833,458 closed, according to the U.S. Small Business Administration. And in a volatile economic climate, survival gets even tougher. Today’s high inflation rates and market instability have small businesses bracing for economic uncertainties, according to the [MetLife & U.S. Chamber of Commerce Small Business Index](https://www.uschamber.com/sbindex/summary).\n\nAnd those numbers are just about sheer survival. That’s not to mention actually gaining a solid foothold in an organization’s industry, attracting loyal customers, and successfully taking on bigger competitors, which just makes the hill small businesses are climbing even steeper.\n\nPrepare to make that climb easier by migrating to a single, end-to-end platform. [Download our SMB-focused ebook](https://page.gitlab.com/resources-ebook-trading-diy-devops-for-a-single-platform-smb.html) learn the advantages to moving from a DIY DevOps toolchain to GitLab’s platform.\n",[1299,9,694,717],{"slug":1379,"featured":6,"template":698},"devsecops-platforms-give-smbs-security-muscle","content:en-us:blog:devsecops-platforms-give-smbs-security-muscle.yml","Devsecops Platforms Give Smbs Security Muscle","en-us/blog/devsecops-platforms-give-smbs-security-muscle.yml","en-us/blog/devsecops-platforms-give-smbs-security-muscle",{"_path":1385,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1386,"content":1392,"config":1400,"_id":1402,"_type":14,"title":1403,"_source":16,"_file":1404,"_stem":1405,"_extension":19},"/en-us/blog/ditch-your-legacy-planning-tool-get-agile-with-gitlab",{"title":1387,"description":1388,"ogTitle":1387,"ogDescription":1388,"noIndex":6,"ogImage":1389,"ogUrl":1390,"ogSiteName":686,"ogType":687,"canonicalUrls":1390,"schema":1391},"Ditch your legacy planning tool: Get Agile with GitLab","Discover how Agile planning in a DevSecOps platform unlocks traceability from idea to implementation, providing a holistic view of your strategy in action.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099116/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%282%29_6IiTrEHgXVZcOI2rcPfg21_1750099116301.png","https://about.gitlab.com/blog/ditch-your-legacy-planning-tool-get-agile-with-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Ditch your legacy planning tool: Get Agile with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Amanda Rueda\"}],\n        \"datePublished\": \"2024-03-14\",\n      }",{"title":1387,"description":1388,"authors":1393,"heroImage":1389,"date":1395,"body":1396,"category":1397,"tags":1398},[1394],"Amanda Rueda","2024-03-14","When organizations are trying to get a better handle on their software development workflows — struggling with bottlenecks and silos, not being able to integrate customer feedback fast enough, and lacking project visibility — they just might turn to Agile planning. It’s a solid way to increase collaboration, foster iterations, and speed value delivery.\n\nAgile planning, though, works even better when done in conjunction with a DevSecOps platform and the methodologies that come along with it. There’s no need to choose one or the other. In fact, they are designed to work together, and both focus on continuous improvement, collaboration, and team empowerment. A DevSecOps platform helps you bring an Agile mindset to software delivery.\n\n> [Contact our sales team](https://about.gitlab.com/sales/) to get started with GitLab Agile planning today!\n\n### What problems can Agile planning and a DevSecOps platform tackle?\n\nFirst off, let’s look at some challenges teams take on with a combination of Agile planning tools and a DevSecOps platform:\n\n- Inefficiencies and bottlenecks - With context switching between a multitude of tools and a lack of visibility into teams’ work and workflows, it’s hard to see bottlenecks where time and effort is being wasted.\n- Silos and lack of collaboration - If planning and development are happening in different places and with different tools, it’s much more difficult for teams to work together to improve efficiency and deployment speed.\n- Problems scaling up - When teams and workflows are growing, it can be difficult to enable cross-functional work that will keep up with increasing demands.\n- Problems with communication - When stakeholders don’t have insight and the ability to comment in the early planning stage of a project, engaging with them becomes inefficient and their valuable views are lost.\n- Losing track of resources - Without visibility into how teams’ time  and work are allocated, it’s easy to lose sight of how valuable resources are being allocated — or even wasted.\n- Keeping up with reports - Without automation to help teams keep up with progress reports, it can be highly taxing to get needed, organized reports on time.\n\nBoth Agile planning tools and a DevSecOps platform focus on bringing customer-facing teams, product teams, and development teams together to accelerate customer feedback into production and speed up development through iterations. Each one works really well, but together they’re even more powerful.\n\n### Learning from Iron Mountain\n\n[Iron Mountain Inc.](https://about.gitlab.com/customers/iron-mountain/), a U.S.-based enterprise information management services company, has embraced Agile methods, but was looking to simplify their fragmented tooling to gain a single view of software development workflows. With an eye on reducing the costs associated with infrastructure management, while also securely increasing production velocity, the company, which has more than 225,000 customers worldwide, adopted a DevSecOps platform to scale their Agile framework. The platform enabled their Agile methodologies, and Agile supported their evolution to DevOps.\n\n“GitLab has provided us with the foundation and platform to enable our scaled Agile framework,” says Hayelom Tadesse, Iron Mountain’s vice president of enterprise technology. “We are able to collaborate within our Enterprise IT teams and our key stakeholders.”\n\n### How Agile planning + a DevSecOps platform helps organizations\n\nAgile is a software development mindset that calls for iterative changes and updates. Instead of creating an initial, one-and-only plan that is seen all the way through the software development lifecycle, Agile planning leaves room to adapt through the development phase, based on feedback from cross-functional teams and customers. Simply put, Agile planning comes into play in every phase of development.\n\nAnd an end-to-end DevSecOps platform fosters collaboration, breaks down silos, and offers visibility into what is happening throughout the software development lifecycle.\nWhen you incorporate Agile planning inside the framework of a DevSecOps platform, it’s easier and more efficient to plan, organize, track, and measure work.\n\nBy [combining Agile and a DevSecOps platform](https://about.gitlab.com/blog/gitlab-enterprise-agile-planning-add-on-for-all-roles/), organizations can:\n- **Optimize workflows** by enabling a unified view of DevSecOps metrics to resolve process bottlenecks and achieve business goals faster. A DevSecOps platform, like GitLab, can solve challenges such as fragmented tooling, gaps that block development and operations communications, administrative burdens, and difficulties with efficiently securing complex pipeline deployments.\n- **Unlock collaboration** to break down silos and drive organizational outcomes. Cross-functional teams work side-by-side in GitLab, fostering open communication and real-time feedback. By sharing ideas and iterating on work from the inception of ideas to deployment to production, everyone remains on the same page.\n- **Simplify design work** since design teams can share mockups, gather feedback, and ensure software alignment with business objectives, all within a single platform.\n- **Enable value stream management** by empowering teams with metrics and insights. A platform helps teams ship better software faster and focus on delivering customer value.\n- **Gain actionable insights** to drive continuous improvement across the entire software delivery process. By bringing Agile planning into a DevSecOps platform, code merges are effortlessly linked to issues, ensuring complete visibility and a user-friendly view of a project’s current status.\n\nIntegrated Agile capabilities bring teams together, fostering a culture of collaboration, transparency, and efficiency. And, within a single platform, it empowers teams to work together, deliver value faster, and ultimately, create software that truly matters.\n\nTake a look at how GitLab can help you plan and track work across the software development lifecycle, removing inefficiencies and scaling software delivery:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/7ICcIaDsVc8?si=5_rf2KLyoE5kuIAM\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n> [Contact our sales team](https://about.gitlab.com/sales/) to get started with GitLab Agile planning today!\n","agile-planning",[1399,9,496],"agile",{"slug":1401,"featured":91,"template":698},"ditch-your-legacy-planning-tool-get-agile-with-gitlab","content:en-us:blog:ditch-your-legacy-planning-tool-get-agile-with-gitlab.yml","Ditch Your Legacy Planning Tool Get Agile With Gitlab","en-us/blog/ditch-your-legacy-planning-tool-get-agile-with-gitlab.yml","en-us/blog/ditch-your-legacy-planning-tool-get-agile-with-gitlab",{"_path":1407,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1408,"content":1414,"config":1419,"_id":1421,"_type":14,"title":1422,"_source":16,"_file":1423,"_stem":1424,"_extension":19},"/en-us/blog/dunelm-strengthens-business-by-enhancing-its-devsecops-culture",{"title":1409,"description":1410,"ogTitle":1409,"ogDescription":1410,"noIndex":6,"ogImage":1411,"ogUrl":1412,"ogSiteName":686,"ogType":687,"canonicalUrls":1412,"schema":1413},"Dunelm strengthens business by enhancing its DevSecOps culture","Learn how a major UK retailer is using GitLab to ensure everyone in their DevSecOps teams can work together, increasing speed, security, and trust.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749670332/Blog/Hero%20Images/groupcollaboration.jpg","https://about.gitlab.com/blog/dunelm-strengthens-business-by-enhancing-its-devsecops-culture","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Dunelm strengthens business by enhancing its DevSecOps culture\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sharon Gaudin\"}],\n        \"datePublished\": \"2023-11-16\",\n      }",{"title":1409,"description":1410,"authors":1415,"heroImage":1411,"date":1416,"body":1417,"category":972,"tags":1418},[756],"2023-11-16","When IT leaders at one of the UK’s largest retailers wanted to better support and strengthen the business, they created a culture where everyone on their DevSecOps teams could work together more naturally.\n\n“DevSecOps is a mindset and mindset is a cultural thing,” said Paul Kerrison, director of Engineering and Architecture at [Dunelm](https://about.gitlab.com/customers/dunelm/), a $1.6 billion (GBP) British home furnishings retailer. “Culture isn’t just a buzzword or something nice to have. There's a genuine value. It builds trust with not just the technology teams but with the wider business as a whole. That allows us to move faster and more safely.”\n\nKerrison, along with Jan Claeyssens, Dunelm’s DevSecOps principal engineer, talked about creating this cultural shift during GitLab’s DevSecOps World Tour event in London this fall. The 44-year-old company, which is traded on the London Stock Exchange and employs more than 11,000 people, adopted GitLab in 2020. They have been using the end-to-end platform to not only increase software development productivity and efficiency but to build inclusive teams that are focused on sharing responsibility for security.\n\nOn stage with Grigoriy Shlyapinkov, strategic customer success manager at GitLab, Claeyssens told the audience it’s been critical to cut out an us-versus-them mentality that existed between developers and security engineers. Working hard to break down those barriers, he said they’ve created a new [cohesive environment](/blog/its-time-to-put-the-sec-in-devsecops/).\n\nDunelm’s DevOps teams had been working together pretty well before the culture shift, but now they’re [collaborating](/blog/5-ways-collaboration-boosts-productivity-and-your-career/) on a different level.\n\n## Embedding security into the team\n\n“I think we can all agree that in 2023 you can no longer say you have good software if it isn't secure,” said Claeyssens. “We have to lean in and really listen to what problems other people are facing, and then figure out how to help them. We all work at Dunelm for the same thing – to [make the business better](/blog/how-devsecops-drives-business-success/). So we need to solve problems together and that’s going to be a continuous journey. This culture will require daily effort.”\n\nThat effort, though, is eased by using GitLab because everyone – from developers to security and the C-suite – can use the end-to-end platform to gain visibility into every project, Claeyssens noted.\n\n“With the platform we can serve all our users where they live,” he said. “It’s one of GitLab’s mantras. If you have everything in one place, all colleagues can see all the features, and in the end, that puts us on a journey together.” \n\n## Making room at the table\n\nKerrison said by rewarding positive behaviors and giving security team members a seat at what had once been an exclusive table, everyone can pick up the security mantle. \n\n“Including security in the leadership team and having them work closely with the engineering teams is key,” he said. “You can’t improve security if it's seen as a second-class citizen.”\n\nAnd part of making it easier for everyone to be aware of and work on security is about using automation features built into the GitLab platform, according to Claeyssens. “The platform is about automating security,” he said. “You have all the security scanners in GitLab – everything. We use the compliance frameworks. The vulnerability scanning. The scan result policies. It makes all our lives a little bit easier.”\n\nThat holistic approach to DevSecOps is what made Dunelm adopt GitLab in the first place. “GitLab sold us on the dream of the whole suite of features, and I'll be honest, I didn't know where GitHub was at the time,” said Claeyssens. “There were only so many contenders. That's how we ended up with GitLab.”\n\n## Looking ahead to working with AI\n\nWhen asked about using artificial intelligence-assisted tools to cut down on DevSecOps workloads, Kerrison said it’s really easy right now to get caught up in all the buzz about AI. Their work with it will likely start, he explained, with using AI for specific tasks, like code generation, vulnerability checks, and refactoring code. Then as it advances, the technology could start to give engineers real-time feedback on code as they’re writing it.\n\nReferencing Star Trek character Captain Jean-Luc Picard asking the starship’s food replicator for “tea, Earl Grey, hot,” Kerrison said he’s looking forward to the day he can order up microservice deliveries and the smart system will create automated testing, along with security and vulnerability scanning. \n\nWhat Kerrison’s really waiting for, though, are AI tools that have actual agency to be predictive, considering what projects and teams need assistance and then launching that work. “It would be much more trusted and can go out to find problems and fix them,” said Kerrison. “Then engineers can start to focus more on the what than the how. That’s where the power will be. Although until AI gets to the place where it can sort and pair socks after they've been through the washing, I don't think we're quite there yet.”\n\n_Dunelm, which uses GitLab Ultimate, has distribution centers, 178 stores, and a robust ecommerce operation. The company sees more than 12 million online transactions per year, while maintaining a large online catalog. More than ever, Dunelm relies on innovative technology engineering to improve customer experiences._\n\n_Read more GitLab customer stories on our [customers page](https://about.gitlab.com/customers/)._",[974,9,496,694],{"slug":1420,"featured":6,"template":698},"dunelm-strengthens-business-by-enhancing-its-devsecops-culture","content:en-us:blog:dunelm-strengthens-business-by-enhancing-its-devsecops-culture.yml","Dunelm Strengthens Business By Enhancing Its Devsecops Culture","en-us/blog/dunelm-strengthens-business-by-enhancing-its-devsecops-culture.yml","en-us/blog/dunelm-strengthens-business-by-enhancing-its-devsecops-culture",{"_path":1426,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1427,"content":1433,"config":1438,"_id":1440,"_type":14,"title":1441,"_source":16,"_file":1442,"_stem":1443,"_extension":19},"/en-us/blog/efficient-devsecops-workflows-hands-on-python-gitlab-api-automation",{"ogTitle":1428,"schema":1429,"ogImage":1430,"ogDescription":1431,"ogSiteName":686,"noIndex":6,"ogType":687,"ogUrl":1432,"title":1428,"canonicalUrls":1432,"description":1431},"Efficient DevSecOps workflows: Hands-on python-gitlab API automation","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Efficient DevSecOps workflows: Hands-on python-gitlab API automation\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Michael Friedrich\"}],\n        \"datePublished\": \"2023-02-01\",\n      }","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659883/Blog/Hero%20Images/post-cover-image.jpg","The python-gitlab library is a useful abstraction layer for the GitLab API. Dive into hands-on examples and best practices in this tutorial.","https://about.gitlab.com/blog/efficient-devsecops-workflows-hands-on-python-gitlab-api-automation",{"title":1428,"description":1431,"authors":1434,"heroImage":1430,"date":1435,"body":1436,"category":909,"tags":1437},[1318],"2023-02-01","A friend once said in a conference presentation, “Manual work is a bug.\"\nWhen there are repetitive tasks in workflows, I tend to [come back to this\nquote](https://twitter.com/dnsmichi/status/1574087419237916672), and try to\nautomate as much as possible. For example, by querying a REST API to do an\ninventory of settings, or calling API actions to create new comments in\nGitLab issues/merge requests. The interaction with the GitLab REST API can\nbe done in different ways, using HTTP requests with curl (or\n[hurl](/blog/how-to-continously-test-web-apps-apis-with-hurl-and-gitlab-ci-cd/))\non the command line, or by writing a script in a programming language. The\nlatter can become reinventing the wheel again with raw HTTP requests code,\nand parsing the JSON responses.\n\n\nThanks to the wider GitLab community, many different languages are supported by API abstraction libraries. They provide support for all API attributes, add helper functions to get/create/delete objects, and generally aim to help developers focus. The [python-gitlab library](https://python-gitlab.readthedocs.io/en/stable/) is a feature-rich and easy-to-use library written in Python.\n\n\nIn this blog post, you will learn about the basic usage of the library by working with API objects, attributes, pagination and resultsets, and dive into more concrete use cases collecting data, printing summaries and writing data to the API to create comments and commits. There is a whole lot more to learn, with many of the use cases inspired by wider community questions on the forum, Hacker News, issues, etc.\n\n\nThis blog post is a long read, so feel free to stick with the beginner's tutorial or skip to the advanced [DevSecOps](https://about.gitlab.com/topics/devsecops/) use cases, development tips and code optimizations by navigating the table of contents:\n\n\n- [Getting started](#getting-started)\n\n- [Configuration](#configuration)\n\n- [Managing objects: The GitLab Object](#managing-objects-the-gitlab-object)\n    - [Objects managers and loading](#objects-managers-and-loading)\n    - [Pagination of results](#pagination-of-results)\n    - [Working with object relationships](#working-with-object-relationships)\n    - [Working with different object collection scopes](#working-with-different-object-collection-scopes)\n- [DevSecOps use cases for API read actions](#devsecops-use-cases-for-api-read-actions)\n    - [List branches by merged state](#list-branches-by-merged-state)\n    - [Print project settings for review: MR approval rules](#print-project-settings-for-review-mr-approval-rules)\n    - [Inventory: Get all CI/CD variables that are protected or masked](#inventory-get-all-cicd-variables-that-are-protected-or-masked)\n    - [Download a file from the repository](#download-a-file-from-the-repository)\n    - [Migration help: List all certificate-based Kubernetes clusters](#migration-help-list-all-certificate-based-kubernetes-clusters)\n    - [Team efficiency: Check if existing merge requests need to be rebased after merging a huge refactoring MR](#team-efficiency-check-if-existing-merge-requests-need-to-be-rebased-after-merging-a-huge-refactoring-mr)\n- [DevSecOps use cases for API write actions](#devsecops-use-cases-for-api-write-actions)\n    - [Move epics between groups](#move-epics-between-groups)\n    - [Compliance: Ensure that project settings are not overridden](#compliance-ensure-that-project-settings-are-not-overridden)\n    - [Taking notes, generate due date overview](#taking-notes-generate-due-date-overview)\n    - [Create issue index in a Markdown file, grouped by labels](#create-issue-index-in-a-markdown-file-grouped-by-labels)\n- [Advanced DevSecOps workflows](#advanced-devsecops-workflows)\n    - [Container images to run API scripts](#container-images-to-run-api-scripts)\n    - [CI/CD integration: Release and changelog generation](#cicd-integration-release-and-changelog-generation)\n    - [CI/CD integration: Pipeline report summaries](#cicd-integration-pipeline-report-summaries)\n- [Development tips](#development-tips)\n    - [Advanced custom configuration](#advanced-custom-configuration)\n    - [CI/CD code linting for different Python versions](#cicd-code-linting-for-different-python-versions)\n- [Optimize code and performance](#optimize-code-and-performance)\n    - [Lazy objects](#lazy-objects)\n    - [Object-oriented programming](#object-oriented-programming)\n- [More use cases](#more-use-cases)\n\n- [Conclusion](#conclusion)\n\n\n## Getting started\n\n\nThe python-gitlab documentation is a great resource for [getting started guides](https://python-gitlab.readthedocs.io/en/stable/api-usage.html), object types and their available methods, and combined workflow examples. Together with the [GitLab API resources documentation](https://docs.gitlab.com/ee/api/api_resources.html), which provides the object attributes that can be used, these are the best resources to get going.\n\n\nThe code examples in this blog post require Python 3.8+, and the `python-gitlab` library. Additional requirements are specified in the `requirements.txt` file – one example requires `pyyaml` for YAML config parsing. To follow and practice the use cases code, it is recommended to clone the project, install the requirements and run the scripts. Example with Homebrew on macOS:\n\n\n```shell\n\ngit clone https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python.git\n\n\ncd gitlab-api-python\n\n\nbrew install python\n\n\npip3 install -r requirements.txt\n\n\npython3 \u003Cscriptname>.py\n\n```\n\n\nThe scripts are intentionally not using a common shared library that provides generic functions for parameter reads, or additional helper functionality, for example. The idea is to show easy-to-follow examples that can be used stand-alone for testing, and only require installing the `python-gitlab` library as a dependency. Improving the code for production use is recommended. This can also help with building a maintained API tooling project that, for example, includes container images and CI/CD templates for developers to consume on a DevSecOps platform.\n\n\n## Configuration\n\n\nWithout configuration, python-gitlab will run unauthenticated requests against the default server `https://gitlab.com`. The most common configuration settings relate to the GitLab instance to connect to, and the authentication method by specifying access tokens. Python-gitlab supports different types of configuration: A configuration file or environment variables.\n\n\nThe [configuration file](https://python-gitlab.readthedocs.io/en/stable/cli-usage.html#cli-configuration) is available for the API library bindings, and the CLI (the CLI is not explained in this blog post). The configuration file supports [credential helpers](https://python-gitlab.readthedocs.io/en/stable/cli-usage.html#credential-helpers) to access tokens directly.\n\n\nEnvironment variables as an alternative configuration method provide an easy way to run the script on terminal, integrate into container images, and prepare them for running in CI/CD pipelines.\n\n\nThe configuration needs to be loaded into the Python script context. Start by importing the `os` library to fetch environment variables using the `os.environ.get()` method. The first parameter specifies the key, the second parameter sets the default value when the variable is not available in the environment.\n\n\n```python\n\nimport os\n\n\ngl_server = os.environ.get('GL_SERVER', 'https://gitlab.com')\n\n\nprint(gl_server)\n\n```\n\n\nThe parametrization on the terminal can happen directly for the command only, or exported into the shell environment.\n\n\n```shell\n\n$ GL_SERVER=’https://gitlab.company.com’ python3 script.py\n\n\n$ export GL_SERVER=’https://gitlab.company.com’\n\n$ python3 script.py\n\n```\n\n\nIt is recommended to add safety checks to ensure that all variables are set before continuing to run the program. The following snippet imports the required libraries, reads the `GL_SERVER` environment variable and expects the user to set the `GL_TOKEN` variable. If not, the script prints and throws errors, and calls `sys.exit(1)` indicating an error status.\n\n\n```python\n\nimport gitlab\n\nimport os\n\nimport sys\n\n\nGITLAB_SERVER = os.environ.get('GL_SERVER', 'https://gitlab.com')\n\nGITLAB_TOKEN = os.environ.get('GL_TOKEN')\n\n\nif not GITLAB_TOKEN:\n    print(\"Please set the GL_TOKEN env variable.\")\n    sys.exit(1)\n```\n\n\nWe will look into a more detailed example now which creates a connection to the API and makes an actual data request.\n\n\n## Managing objects: The GitLab object\n\n\nAny interaction with the API requires the GitLab object to be instantiated. This is the entry point to configure the GitLab server to connect, authenticate using access tokens, and more global settings for pagination, object loading and more.\n\n\nThe following example runs an unauthenticated request against GitLab.com. It is possible to access public API endpoints and for example get a specific [.gitignore template for Python](https://python-gitlab.readthedocs.io/en/stable/gl_objects/templates.html#gitignore-templates).\n\n\n[python_gitlab_object_unauthenticated.py](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/python_gitlab_object_unauthenticated.py)\n\n\n```python\n\nimport gitlab\n\n\ngl = gitlab.Gitlab()\n\n\n# Get .gitignore templates without authentication\n\ngitignore_templates = gl.gitignores.get('Python')\n\n\nprint(gitignore_templates.content)\n\n```\n\n\nThe next sections provide more insights into:\n\n\n- [Objects managers and loading](#objects-managers-and-loading)\n\n- [Pagination of results](#pagination-of-results)\n\n- [Working with object relationships](#working-with-object-relationships)\n\n- [Working with different object collection scopes](#working-with-different-object-collection-scopes)\n\n\n### Objects managers and loading\n\n\nThe python-gitlab library provides access to GitLab resources using so-called “[managers](https://python-gitlab.readthedocs.io/en/stable/api-usage.html#managers)\". Each manager type implements methods to work with the datasets (list, get, etc.).\n\n\nThe script shows how to access subgroups, direct projects, all projects including subgroups, issues, epics and todos. These methods and API endpoint require authentication to access all attributes. The code snippet, therefore, uses variables to get the authentication token, and also uses the `GROUP_ID` variable to specify a main group at which to start searching.\n\n\n```python\n\n#!/usr/bin/env python\n\n\nimport gitlab\n\nimport os\n\nimport sys\n\n\nGITLAB_SERVER = os.environ.get('GL_SERVER', 'https://gitlab.com')\n\n# https://gitlab.com/gitlab-de/use-cases/\n\nGROUP_ID = os.environ.get('GL_GROUP_ID', 16058698)\n\nGITLAB_TOKEN = os.environ.get('GL_TOKEN')\n\n\nif not GITLAB_TOKEN:\n    print(\"Please set the GL_TOKEN env variable.\")\n    sys.exit(1)\n\ngl = gitlab.Gitlab(GITLAB_SERVER, private_token=GITLAB_TOKEN)\n\n\n# Main\n\nmain_group = gl.groups.get(GROUP_ID)\n\n\nprint(\"Sub groups\")\n\nfor sg in main_group.subgroups.list():\n    print(\"Subgroup name: {sg}\".format(sg=sg.name))\n\nprint(\"Projects (direct)\")\n\nfor p in main_group.projects.list():\n    print(\"Project name: {p}\".format(p=p.name))\n\nprint(\"Projects (including subgroups)\")\n\nfor p in main_group.projects.list(include_subgroups=True, all=True):\n     print(\"Project name: {p}\".format(p=p.name))\n\nprint(\"Issues\")\n\nfor i in main_group.issues.list(state='opened'):\n    print(\"Issue title: {t}\".format(t=i.title))\n\nprint(\"Epics\")\n\nfor e in main_group.issues.list():\n    print(\"Epic title: {t}\".format(t=e.title))\n\nprint(\"Todos\")\n\nfor t in gl.todos.list(state='pending'):\n    print(\"Todo: {t} url: {u}\".format(t=t.body, u=t.target_url\n```\n\n\nYou can run the script [`python_gitlab_object_manager_methods.py`](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/python_gitlab_object_manager_methods.py) by overriding the `GROUP_ID` variable on GitLab.com SaaS for your own group to analyze. The `GL_SERVER` variable needs to be specified for self-managed instance targets. `GL_TOKEN` must provide the personal access token.\n\n\n```shell\n\nexport GL_TOKEN=xxx\n\n\nexport GL_SERVER=”https://gitlab.company.com”\n\n\nexport GL_SERVER=”https://gitlab.com”\n\n\nexport GL_GROUP_ID=1234\n\n\npython3 python_gitlab_object_manager_methods.py\n\n```\n\n\nGoing forward, the example snippets won’t show the Python headers and environment variable parsing to focus on the algorithm and functionality. All scripts are open source under the MIT license and available in [this project](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python).\n\n\n### Pagination of results\n\n\nBy default, the GitLab API does not return all result sets and requires the clients to use [pagination](https://docs.gitlab.com/ee/api/rest/index.html#pagination) to iterate through all result pages. The python-gitlab library [allows users to specify the settings](https://python-gitlab.readthedocs.io/en/stable/api-usage.html#pagination) globally in the GitLab object, or on each `list()` call. By default, all result sets would fire API requests, which can slow down the script execution. The recommended way is using `iterator=True` which returns a generator object, and API calls are fired on-demand when accessing the object.\n\n\nThe following example searches for the group name `everyonecancontribute`, and uses keyset pagination with 100 results on each page. The iterator is set to true on `gl.groups.list(iterator=True)` to fetch new result sets on demand. If the searched group name is found, the loop breaks and prints a summary, including measuring the duration of the complete search request.\n\n\n```python\n\nSEARCH_GROUP_NAME=\"everyonecancontribute\"\n\n\n# Use keyset pagination\n\n# https://python-gitlab.readthedocs.io/en/stable/api-usage.html#pagination\n\ngl = gitlab.Gitlab(GITLAB_SERVER, private_token=GITLAB_TOKEN,\n    pagination=\"keyset\", order_by=\"id\", per_page=100)\n\n# Iterate over the list, and fire new API calls in case the result set does not match yet\n\ngroups = gl.groups.list(iterator=True)\n\n\nfound_page = 0\n\nstart = timer()\n\n\nfor group in groups:\n    if SEARCH_GROUP_NAME == group.name:\n        # print(group) # debug\n        found_page = groups.current_page\n        break\n\nend = timer()\n\n\nduration = f'{end-start:.2f}'\n\n\nif found_page > 0:\n    print(\"Pagination API example for Python with GitLab{desc} - found group {g} on page {p}, duration {d}s\".format(\n        desc=\", the DevSecOps platform\", g=SEARCH_GROUP_NAME, p=found_page, d=duration))\nelse:\n    print(\"Could not find group name '{g}', duration {d}\".format(g=SEARCH_GROUP_NAME, d=duration))\n```\n\n\nExecuting `python_gitlab_pagination.py` found the [everyonecancontribute group](https://gitlab.com/everyonecancontribute) on page 5.\n\n\n```shell\n\n$ python3 python_gitlab_pagination.py\n\nPagination API example for Python with GitLab, the DevSecOps platform - found group everyonecancontribute on page 5, duration 8.51s\n\n```\n\n\n### Working with object relationships\n\n\nWhen working with object relationships – for example, collecting all projects in a given group – additional steps need to be taken. The returned project objects provide limited attributes by default. Manageable objects require an additional `get()` call which requests the full project object from the API in the background. This on-demand workflow helps to avoid waiting times and traffic by reducing the immediately returned attributes.\n\n\nThe following example illustrates the problem by looping through all projects in a group, and tries to call the `project.branches.list()` function, raising an exception in the try/except flow. The second example gets a manageable project object and tries the function call again.\n\n\n```python\n\n# Main\n\ngroup = gl.groups.get(GROUP_ID)\n\n\n# Collect all projects in group and subgroups\n\nprojects = group.projects.list(include_subgroups=True, all=True)\n\n\nfor project in projects:\n    # Try running a method on a weak object\n    try:\n       print(\"🤔 Project: {pn} 💡 Branches: {b}\\n\".format(\n        pn=project.name,\n        b=\", \".join([x.name for x in project.branches.list()])))\n    except Exception as e:\n        print(\"Got exception: {e} \\n ===================================== \\n\".format(e=e))\n\n    # Retrieve a full manageable project object\n    # https://python-gitlab.readthedocs.io/en/stable/gl_objects/groups.html#examples\n    manageable_project = gl.projects.get(project.id)\n\n    # Print a method available on a manageable object\n    print(\"🤔 Project: {pn} 💡 Branches: {b}\\n\".format(\n        pn=manageable_project.name,\n        b=\", \".join([x.name for x in manageable_project.branches.list()])))\n```\n\n\nThe exception handler in the python-gitlab library prints the error message, and also links to the documentation. It is helpful to take a debugging note that objects might not be available to manage whenever you cannot access object attributes or function calls.\n\n\n```shell\n\n$ python3 python_gitlab_manageable_objects.py\n\n\n🤔 Project: GitLab API Playground 💡 Branches: cicd-demo-automated-comments, docs-mr-approval-settings, main\n\n\nGot exception: 'GroupProject' object has no attribute 'branches'\n\n\n\u003Cclass 'gitlab.v4.objects.projects.GroupProject'> was created via a\n\nlist() call and only a subset of the data may be present. To ensure\n\nall data is present get the object using a get(object.id) call. For\n\nmore details, see:\n\n\nhttps://python-gitlab.readthedocs.io/en/v3.8.1/faq.html#attribute-error-list\n =====================================\n```\n\n\nThe full script is located [here](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/python_gitlab_manageable_objects.py).\n\n\n### Working with different object collection scopes\n\n\nSometimes, the script needs to collect all projects from a self-managed instance, or from a group with subgroups, or from a single project. The latter is helpful for faster testing on the required attributes, and the group fetch helps with testing at scale later. The following snippet collects all project objects into the `projects` list, and appends objects from different incoming configuration. You will also see the manageable object pattern for project in groups again.\n\n\n```python\n    # Collect all projects, or prefer projects from a group id, or a project id\n    projects = []\n\n    # Direct project ID\n    if PROJECT_ID:\n        projects.append(gl.projects.get(PROJECT_ID))\n\n    # Groups and projects inside\n    elif GROUP_ID:\n        group = gl.groups.get(GROUP_ID)\n\n        for project in group.projects.list(include_subgroups=True, all=True):\n            # https://python-gitlab.readthedocs.io/en/stable/gl_objects/groups.html#examples\n            manageable_project = gl.projects.get(project.id)\n            projects.append(manageable_project)\n\n    # All projects on the instance (may take a while to process)\n    else:\n        projects = gl.projects.list(get_all=True)\n```\n\n\nThe full example is located in [this script](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/get_mr_approval_rules.py) for listing MR approval rules settings for specified project targets.\n\n\n## DevSecOps use cases for API read actions\n\n\nThe authenticated access token needs [`read_api` scope](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#personal-access-token-scopes).\n\n\nThe following use cases are discussed:\n\n\n- [List branches by merged state](#list-branches-by-merged-state)\n\n- [Print project settings for review: MR approval rules](#print-project-settings-for-review-mr-approval-rules)\n\n- [Inventory: Get all CI/CD variables that are protected or masked](#inventory-get-all-cicd-variables-that-are-protected-or-masked)\n\n- [Download a file from the repository](#download-a-file-from-the-repository)\n\n- [Migration help: List all certificate-based Kubernetes clusters](#migration-help-list-all-certificate-based-kubernetes-clusters)\n\n- [Team efficiency: Check if existing merge requests need to be rebased after merging a huge refactoring MR](#team-efficiency-check-if-existing-merge-requests-need-to-be-rebased-after-merging-a-huge-refactoring-mr)\n\n\n### List branches by merged state\n\n\nA common ask is to do some Git housekeeping in the project, and see how many merged and unmerged branches are floating around. [A question on the GitLab community forum](https://forum.gitlab.com/t/python-gitlab-project-branch-list-filter/80257) about filtering branch listings inspired me look into writing a [script](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/get_branches_by_state.py) that helps achieve this goal. The `branches.list()` method returns all branch objects that are stored in a temporary list for later processing for two loops: Collecting merged branch names, and not merged branch names. The `merged` attribute on the `branch` object is a boolean value indicating whether the branch has been merged.\n\n\n```python\n\nproject = gl.projects.get(PROJECT_ID, lazy=False, pagination=\"keyset\", order_by=\"updated_at\", per_page=100)\n\n\n# Get all branches\n\nreal_branches = []\n\nfor branch in project.branches.list():\n    real_branches.append(branch)\n\nprint(\"All branches\")\n\nfor rb in real_branches:\n    print(\"Branch: {b}\".format(b=rb.name))\n\n# Get all merged branches\n\nmerged_branches_names = []\n\nfor branch in real_branches:\n    if branch.default:\n        continue # ignore the default branch for merge status\n\n    if branch.merged:\n        merged_branches_names.append(branch.name)\n\nprint(\"Branches merged: {b}\".format(b=\", \".join(merged_branches_names)))\n\n\n# Get un-merged branches\n\nnot_merged_branches_names = []\n\nfor branch in real_branches:\n    if branch.default:\n        continue # ignore the default branch for merge status\n\n    if not branch.merged:\n        not_merged_branches_names.append(branch.name)\n\nprint(\"Branches not merged: {b}\".format(b=\", \".join(not_merged_branches_names)))\n\n```\n\n\nThe workflow is intentionally a step-by-step read, you can practice optimizing the Python code for the conditional branch name collection.\n\n\n\n### Print project settings for review: MR approval rules\n\n\nThe following [script](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/get_mr_approval_rules.py) walks through all collected project objects, and checks whether approval rules are specified. If the list length is greater than zero, it loops over the list and prints the settings using a JSON pretty-print method.\n\n\n```python\n    # Loop over projects and print the settings\n    # https://python-gitlab.readthedocs.io/en/stable/gl_objects/merge_request_approvals.html\n    for project in projects:\n        if len(project.approvalrules.list()) > 0:\n            #print(project) #debug\n            print(\"# Project: {name}, ID: {id}\\n\\n\".format(name=project.name_with_namespace, id=project.id))\n            print(\"[MR Approval settings]({url}/-/settings/merge_requests)\\n\\n\".format(url=project.web_url))\n\n            for ar in project.approvalrules.list():\n                print(\"## Approval rule: {name}, ID: {id}\".format(name=ar.name, id=ar.id))\n                print(\"\\n```json\\n\")\n                print(json.dumps(ar.attributes, indent=2)) # TODO: can be more beautiful, but serves its purpose with pretty print JSON\n                print(\"\\n```\\n\")\n\n```\n\n\n### Inventory: Get all CI/CD variables that are protected or masked\n\n\n[CI/CD variables](https://docs.gitlab.com/ee/ci/variables/) are helpful for pipeline parameterization, and can be configured globally on the instance, in groups and in projects. Secrets, passwords and otherwise sensitive information could be stored there, too. Sometimes it can be necessary to get an overview of all CI/CD variables that are either protected or masked to get a sense of how many variables need to be updated when rotating tokens for example.\n\n\nThe following [script](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/get_all_cicd_variables_masked_or_protected.py) gets all groups and projects and tries to collect the CI/CD variables from the global instance (requires admin permissions), groups and projects (requires maintainer/owner permissions). It prints all CI/CD variables that are either protected or masked, adding that a potential secret value is stored.\n\n\n```python\n\n#!/usr/bin/env python\n\n\nimport gitlab\n\nimport os\n\nimport sys\n\n\n# Helper function to evaluate secrets and print the variables\n\ndef eval_print_var(var):\n    if var.protected or var.masked:\n        print(\"🛡️🛡️🛡️ Potential secret: Variable '{name}', protected {p}, masked: {m}\".format(name=var.key,p=var.protected,m=var.masked))\n\nGITLAB_SERVER = os.environ.get('GL_SERVER', 'https://gitlab.com')\n\nGITLAB_TOKEN = os.environ.get('GL_TOKEN') # token requires maintainer+ permissions. Instance variables require admin access.\n\nPROJECT_ID = os.environ.get('GL_PROJECT_ID') #optional\n\nGROUP_ID = os.environ.get('GL_GROUP_ID', 8034603) # https://gitlab.com/everyonecancontribute\n\n\nif not GITLAB_TOKEN:\n    print(\"🤔 Please set the GL_TOKEN env variable.\")\n    sys.exit(1)\n\ngl = gitlab.Gitlab(GITLAB_SERVER, private_token=GITLAB_TOKEN)\n\n\n# Collect all projects, or prefer projects from a group id, or a project id\n\nprojects = []\n\n# Collect all groups, or prefer group from a group id\n\ngroups = []\n\n\n# Direct project ID\n\nif PROJECT_ID:\n    projects.append(gl.projects.get(PROJECT_ID))\n\n# Groups and projects inside\n\nelif GROUP_ID:\n    group = gl.groups.get(GROUP_ID)\n\n    for project in group.projects.list(include_subgroups=True, all=True):\n        # https://python-gitlab.readthedocs.io/en/stable/gl_objects/groups.html#examples\n        manageable_project = gl.projects.get(project.id)\n        projects.append(manageable_project)\n\n    groups.append(group)\n\n# All projects/groups on the instance (may take a while to process, use iterators to fetch on-demand).\n\nelse:\n    projects = gl.projects.list(iterator=True)\n    groups = gl.groups.list(iterator=True)\n\nprint(\"# List of all CI/CD variables marked as secret (instance, groups, projects)\")\n\n\n# https://python-gitlab.readthedocs.io/en/stable/gl_objects/variables.html\n\n\n# Instance variables (if the token has permissions)\n\nprint(\"Instance variables, if accessible\")\n\ntry:\n    for i_var in gl.variables.list(iterator=True):\n        eval_print_var(i_var)\nexcept:\n    print(\"No permission to fetch global instance variables, continueing without.\")\n    print(\"\\n\")\n\n# group variables (maintainer permissions for groups required)\n\nfor group in groups:\n    print(\"Group {n}, URL: {u}\".format(n=group.full_path, u=group.web_url))\n    for g_var in group.variables.list(iterator=True):\n        eval_print_var(g_var)\n\n    print(\"\\n\")\n\n# Loop over projects and print the settings\n\nfor project in projects:\n    # skip archived projects, they throw 403 errors\n    if project.archived:\n        continue\n\n    print(\"Project {n}, URL: {u}\".format(n=project.path_with_namespace, u=project.web_url))\n    for p_var in project.variables.list(iterator=True):\n        eval_print_var(p_var)\n\n    print(\"\\n\")\n```\n\n\nThe script intentionally does not print the variable values, this is left as an exercise for safe environments. The recommended way of storing secrets is to [use external providers](https://docs.gitlab.com/ee/ci/secrets/).\n\n\n### Download a file from the repository\n\n\nThe [script](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/get_raw_file_content.py) goal is download a file path from a specified branch name, and store its content in a new file.\n\n\n```python\n\n# Goal: Try to download README.md from https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/README.md\n\nFILE_NAME = 'README.md'\n\nBRANCH_NAME = 'main'\n\n\n# Search the file in the repository tree and get the raw blob\n\nfor f in project.repository_tree():\n    print(\"File path '{name}' with id '{id}'\".format(name=f['name'], id=f['id']))\n\n    if f['name'] == FILE_NAME:\n        f_content = project.repository_raw_blob(f['id'])\n        print(f_content)\n\n# Alternative approach: Get the raw file from the main branch\n\nraw_content = project.files.raw(file_path=FILE_NAME, ref=BRANCH_NAME)\n\nprint(raw_content)\n\n\n# Store the file on disk\n\nwith open('raw_README.md', 'wb') as f:\n    project.files.raw(file_path=FILE_NAME, ref=BRANCH_NAME, streamed=True, action=f.write)\n```\n\n\n### Migration help: List all certificate-based Kubernetes clusters\n\n\nThe certificate-based integration of Kubernetes clusters into GitLab [was deprecated](https://docs.gitlab.com/ee/update/deprecations.html#self-managed-certificate-based-integration-with-kubernetes). To help with migration plans, the inventory of existing groups and projects can be automated using the GitLab API.\n\n\n\n```python\n\ngroups = [ ]\n\n\n# get GROUP_ID group\n\ngroups.append(gl.groups.get(GROUP_ID))\n\n\nfor group in groups:\n    for sg in group.subgroups.list(include_subgroups=True, all=True):\n        real_group = gl.groups.get(sg.id)\n        groups.append(real_group)\n\ngroup_clusters = {}\n\nproject_clusters = {}\n\n\nfor group in groups:\n    #Collect group clusters\n    g_clusters = group.clusters.list()\n\n    if len(g_clusters) > 0:\n        group_clusters[group.id] = g_clusters\n\n    # Collect all projects in group and subgroups and their clusters\n    projects = group.projects.list(include_subgroups=True, all=True)\n\n    for project in projects:\n        # https://python-gitlab.readthedocs.io/en/stable/gl_objects/groups.html#examples\n        manageable_project = gl.projects.get(project.id)\n\n        # skip archived projects\n        if project.archived:\n            continue\n\n        p_clusters = manageable_project.clusters.list()\n\n        if len(p_clusters) > 0:\n            project_clusters[project.id] = p_clusters\n\n# Print summary\n\nprint(\"## Group clusters\\n\\n\")\n\nfor g_id, g_clusters in group_clusters.items():\n    url = gl.groups.get(g_id).web_url\n    print(\"Group ID {g_id}: {u}\\n\\n\".format(g_id=g_id, u=url))\n    print_clusters(g_clusters)\n\nprint(\"## Project clusters\\n\\n\")\n\nfor p_id, p_clusters in project_clusters.items():\n    url = gl.projects.get(p_id).web_url\n    print(\"Project ID {p_id}: {u}\\n\\n\".format(p_id=p_id, u=url))\n    print_clusters(p_clusters)\n```\n\n\nThe full script is available [here](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/list_cert_based_kubernetes_clusters.py).\n\n\n### Team efficiency: Check if existing merge requests need to be rebased after merging a huge refactoring MR\n\n\nThe [GitLab handbook](https://handbook.gitlab.com/handbook/) repository is a large monorepo with many merge requests created, reviewed, approved and merged. Some reviews take longer than others, and some merge requests touch multiple pages when renaming a string, or [all handbook pages](/handbook/about/#count-handbook-pages). The marketing handbook needed restructuring (think of code refactoring), and as such, many directories and paths were moved or renamed. [The issue tasks](https://gitlab.com/gitlab-com/www-gitlab-com/-/issues/13991#tasks) grew over time, and I was worried that other merge requests would run into conflicts after merging the huge changes. I remembered that the python-gitlab can fetch all merge requests in a given project, including details on the Git branch, source paths changed and much more.\n\n\nThe resulting script configures a list of source paths that are touched by all merge requests, and checks against the merge request diff with `mr.diffs.list()` and comparing if a pattern matches against the value in `old_path`. If a match is found, the script logs it, and saves the merge request in the `seen_mr` dictionary for the summary later. There are additional attributes collected to allow printing a Markdown task list with URLs for easier copy-paste into [issue descriptions](https://gitlab.com/gitlab-com/www-gitlab-com/-/issues/13991#additional-tasks). The full script is located [here](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/search_mr_contains_updated_path.py).\n\n\n\n```python\n\nPATH_PATTERNS = [\n    'path/to/handbook/source/page.md',\n]\n\n\n# Only list opened MRs\n\n# https://python-gitlab.readthedocs.io/en/stable/gl_objects/merge_requests.html#project-merge-requests\n\nmrs = project.mergerequests.list(state='opened', iterator=True)\n\n\nseen_mr = {}\n\n\nfor mr in mrs:\n    # https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-request-diffs\n    real_mr = project.mergerequests.get(mr.get_id())\n    real_mr_id = real_mr.attributes['iid']\n    real_mr_url = real_mr.attributes['web_url']\n\n    for diff in real_mr.diffs.list(iterator=True):\n        real_diff = real_mr.diffs.get(diff.id)\n\n        for d in real_diff.attributes['diffs']:\n            for p in PATH_PATTERNS:\n                if p in d['old_path']:\n                    print(\"MATCH: {p} in MR {mr_id}, status '{s}', title '{t}' - URL: {mr_url}\".format(\n                        p=p,\n                        mr_id=real_mr_id,\n                        s=mr_status,\n                        t=real_mr.attributes['title'],\n                        mr_url=real_mr_url))\n\n                    if not real_mr_id in seen_mr:\n                        seen_mr[real_mr_id] = real_mr\n\nprint(\"\\n# MRs to update\\n\")\n\n\nfor id, real_mr in seen_mr.items():\n    print(\"- [ ] !{mr_id} - {mr_url}+ Status: {s}, Title: {t}\".format(\n        mr_id=id,\n        mr_url=real_mr.attributes['web_url'],\n        s=real_mr.attributes['detailed_merge_status'],\n        t=real_mr.attributes['title']))\n```\n\n\n\n## DevSecOps use cases for API write actions\n\n\nThe authenticated access token needs full [`api` scope](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#personal-access-token-scopes).\n\n\nThe following use cases are discussed:\n\n\n- [Move epics between groups](#move-epics-between-groups)\n\n- [Compliance: Ensure that project settings are not overridden](#compliance-ensure-that-project-settings-are-not-overridden)\n\n- [Taking notes, generate due date overview](#taking-notes-generate-due-date-overview)\n\n- [Create issue index in a Markdown file, grouped by labels](#create-issue-index-in-a-markdown-file-grouped-by-labels)\n\n\n### Move epics between groups\n\n\nSometimes it is necessary to move epics, similar to issues, into a different group. A question in the GitLab marketing Slack channel inspired me to look into a [feature proposal for the UI](https://gitlab.com/gitlab-org/gitlab/-/issues/12689), [quick actions](/blog/improve-your-gitlab-productivity-with-these-10-tips/), and later, thinking about writing an API script to automate the steps. The idea is simple: Move an epic from a source group to a target group, and copy its title, description and labels. Since epics allow to group issues, they need to be reassigned to the target epic, too. Parent-child epic relationships need to be taken into account to: All child epics of the source epics need to be reassigned to the target epic.\n\n\nThe following script looks up all source [epic attributes](https://python-gitlab.readthedocs.io/en/stable/gl_objects/epics.html) first, and then creates a new target epic with minimal attributes: title and description. The labels list is copied and the changes are persisted with the `save()` call. The issues assigned to the epic need to be re-created in the target epic. The `create()` call actually creates the relationship item, not a new issue object itself. The child epics move requires a different approach, since the relationship is vice versa: The `parent_id` on the child epic needs to be compared against the source epic ID, and if matching, updated to the target epic ID. After copying everything successfully, the source epic needs to be changed into the `closed` state.\n\n\n\n```python\n\n#!/usr/bin/env python\n\n\n# Description: Show how epics can be moved between groups, including title, description, labels, child epics and issues.\n\n# Requirements: python-gitlab Python libraries. GitLab API write access, and maintainer access to all configured groups/projects.\n\n# Author: Michael Friedrich \u003Cmfriedrich@gitlab.com>\n\n# License: MIT, (c) 2023-present GitLab B.V.\n\n\nimport gitlab\n\nimport os\n\nimport sys\n\n\nGITLAB_SERVER = os.environ.get('GL_SERVER', 'https://gitlab.com')\n\n# https://gitlab.com/gitlab-de/use-cases/gitlab-api\n\nSOURCE_GROUP_ID = os.environ.get('GL_SOURCE_GROUP_ID', 62378643)\n\n# https://gitlab.com/gitlab-de/use-cases/gitlab-api/epic-move-target\n\nTARGET_GROUP_ID = os.environ.get('GL_TARGET_GROUP_ID', 62742177)\n\n# https://gitlab.com/groups/gitlab-de/use-cases/gitlab-api/-/epics/1\n\nEPIC_ID = os.environ.get('GL_EPIC_ID', 1)\n\nGITLAB_TOKEN = os.environ.get('GL_TOKEN')\n\n\nif not GITLAB_TOKEN:\n    print(\"Please set the GL_TOKEN env variable.\")\n    sys.exit(1)\n\ngl = gitlab.Gitlab(GITLAB_SERVER, private_token=GITLAB_TOKEN)\n\n\n# Main\n\n# Goal: Move epic to target group, including title, body, labels, and child epics and issues.\n\nsource_group = gl.groups.get(SOURCE_GROUP_ID)\n\ntarget_group = gl.groups.get(TARGET_GROUP_ID)\n\n\n# Create a new target epic and copy all its items, then close the source epic.\n\nsource_epic = source_group.epics.get(EPIC_ID)\n\n# print(source_epic) #debug\n\n\nepic_title = source_epic.title\n\nepic_description = source_epic.description\n\nepic_labels = source_epic.labels\n\nepic_issues = source_epic.issues.list()\n\n\n# Create the epic with minimal attributes\n\ntarget_epic = target_group.epics.create({\n    'title': epic_title,\n    'description': epic_description,\n})\n\n\n# Assign the list\n\ntarget_epic.labels = epic_labels\n\n\n# Persist the changes in the new epic\n\ntarget_epic.save()\n\n\n# Epic issues need to be re-assigned in a loop\n\nfor epic_issue in epic_issues:\n    ei = target_epic.issues.create({'issue_id': epic_issue.id})\n\n# Child epics need to update their parent_id to the new epic\n\n# Need to search in all epics, use lazy object loading\n\nfor sge in source_group.epics.list(lazy=True):\n    # this epic has the source epic as parent epic?\n    if sge.parent_id == source_epic.id:\n        # Update the parent id\n        sge.parent_id = target_epic.id\n        sge.save()\n\nprint(\"Copied source epic {source_id} ({source_url}) to target epic {target_id} ({target_url})\".format(\n    source_id=source_epic.id, source_url=source_epic.web_url,\n    target_id=target_epic.id, target_url=target_epic.web_url))\n\n# Close the old epic\n\nsource_epic.state_event = 'close'\n\nsource_epic.save()\n\nprint(\"Closed source epic {source_id} ({source_url})\".format(\n    source_id=source_epic.id, source_url=source_epic.web_url))\n\n```\n\n\n\n```shell\n\n$  python3 move_epic_between_groups.py\n\nCopied source epic 725341 (https://gitlab.com/groups/gitlab-de/use-cases/gitlab-api/-/epics/1) to target epic 725358 (https://gitlab.com/groups/gitlab-de/use-cases/gitlab-api/epic-move-target/-/epics/6)\n\nClosed source epic 725341 (https://gitlab.com/groups/gitlab-de/use-cases/gitlab-api/-/epics/1)\n\n```\n\n\n\nThe [target epic](https://gitlab.com/groups/gitlab-de/use-cases/gitlab-api/epic-move-target/-/epics/5) was created and shows the expected result: Same title, description, labels, child epic, and issues.\n\n\n![Target epic which has all attributes copied from the source epic: title, description, labels, child epics, issues](/images/blogimages/efficient-devsecops-workflows-python-gitlab-handson/python_gitlab_moved_epic_with_all_attributes.png){: .shadow}\n\n\n**Exercise**: The script does not copy [comments](https://python-gitlab.readthedocs.io/en/stable/gl_objects/notes.html) and [discussion threads](https://python-gitlab.readthedocs.io/en/stable/gl_objects/discussions.html) yet. Research and help update the script – merge requests welcome!\n\n\n\n### Compliance: Ensure that project settings are not overridden\n\n\nProject and group settings may be accidentally changed by team members with maintainer permissions. Compliance requirements need to be met. Another use case is to manage configuration with Infrastructure as Code tools, and ensure that GitLab instance/group/project/etc. configuration is persisted and always the same. Tools like Ansible or Terraform can invoke an API script, or use the python-gitlab library to perform tasks to manage settings.\n\n\nThe following example only has the `main` branch protected.\n\n\n![GitLab project settings for repositories and protected branches, main branch](/images/blogimages/efficient-devsecops-workflows-python-gitlab-handson/python_gitlab_protected_branches_settings_main.png){: .shadow}\n\n\nLet us assume that a new `production` branch has been added and should be protected, too. The following [script](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/enforce_protected_branches.py) defines the dictionary of protected branches and their access levels for push/merge permissions to maintainer level, and builds the comparison logic around the [python-gitlab protected branches documentation](https://python-gitlab.readthedocs.io/en/stable/gl_objects/protected_branches.html).\n\n\n\n```python\n\n#!/usr/bin/env python\n\n\nimport gitlab\n\nimport os\n\nimport sys\n\n\nGITLAB_SERVER = os.environ.get('GL_SERVER', 'https://gitlab.com')\n\n# https://gitlab.com/gitlab-de/use-cases/\n\nGROUP_ID = os.environ.get('GL_GROUP_ID', 16058698)\n\nGITLAB_TOKEN = os.environ.get('GL_TOKEN')\n\n\nPROTECTED_BRANCHES = {\n    'main': {\n        'merge_access_level': gitlab.const.AccessLevel.MAINTAINER,\n        'push_access_level': gitlab.const.AccessLevel.MAINTAINER\n    },\n    'production': {\n        'merge_access_level': gitlab.const.AccessLevel.MAINTAINER,\n        'push_access_level': gitlab.const.AccessLevel.MAINTAINER\n    },\n}\n\n\nif not GITLAB_TOKEN:\n    print(\"Please set the GL_TOKEN env variable.\")\n    sys.exit(1)\n\ngl = gitlab.Gitlab(GITLAB_SERVER, private_token=GITLAB_TOKEN)\n\n\n# Main\n\ngroup = gl.groups.get(GROUP_ID)\n\n\n# Collect all projects in group and subgroups\n\nprojects = group.projects.list(include_subgroups=True, all=True)\n\n\nfor project in projects:\n    # Retrieve a full manageable project object\n    # https://python-gitlab.readthedocs.io/en/stable/gl_objects/groups.html#examples\n    manageable_project = gl.projects.get(project.id)\n\n    # https://python-gitlab.readthedocs.io/en/stable/gl_objects/protected_branches.html\n    protected_branch_names = []\n\n    for pb in manageable_project.protectedbranches.list():\n        manageable_protected_branch = manageable_project.protectedbranches.get(pb.name)\n        print(\"Protected branch name: {n}, merge_access_level: {mal}, push_access_level: {pal}\".format(\n            n=manageable_protected_branch.name,\n            mal=manageable_protected_branch.merge_access_levels,\n            pal=manageable_protected_branch.push_access_levels\n        ))\n\n        protected_branch_names.append(manageable_protected_branch.name)\n\n    for branch_to_protect, levels in PROTECTED_BRANCHES.items():\n        # Fix missing protected branches\n        if branch_to_protect not in protected_branch_names:\n            print(\"Adding branch {n} to protected branches settings\".format(n=branch_to_protect))\n            p_branch = manageable_project.protectedbranches.create({\n                'name': branch_to_protect,\n                'merge_access_level': gitlab.const.AccessLevel.MAINTAINER,\n                'push_access_level': gitlab.const.AccessLevel.MAINTAINER\n            })\n```\n\n\nRunning the script prints the existing `main` branch, and a note that `production` will be updated. The screenshot from the repository settings proves this action.\n\n\n```\n\n$ python3 enforce_protected_branches.py                                                ─╯\n\nProtected branch name: main, merge_access_level: [{'id': 67294702, 'access_level': 40, 'access_level_description': 'Maintainers', 'user_id': None, 'group_id': None}], push_access_level: [{'id': 68546039, 'access_level': 40, 'access_level_description': 'Maintainers', 'user_id': None, 'group_id': None}]\n\nAdding branch production to protected branches settings\n\n```\n\n\n![GitLab project settings for repositories and protected branches, main and production branch](/images/blogimages/efficient-devsecops-workflows-python-gitlab-handson/python_gitlab_protected_branches_settings_main_production.png){: .shadow}\n\n\n\n### Taking notes, generate due date overview\n\n\nA [Hacker News discussion about note-taking tools](https://news.ycombinator.com/item?id=32155848) inspired me to take a look into creating a Markdown table overview, fetched from files that take notes, and sorted by the parsed due date. The script is located [here](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/generate_snippets_index_by_due_date.py) and more complex to understand.\n\n\n```\n\n# 2022-07-19 Notes\n\n\nHN topic about taking notes: https://news.ycombinator.com/item?id=32152935\n\n\n\u003C!--\n\n---\n\nTags: DevOps, Learn\n\nDue: 2022-08-01\n\n---\n\n-->\n\n\n```\n\n\n### Create issue index in a Markdown file, grouped by labels\n\n\nA similar Hacker News question inspired me to write a [script](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/generate_issue_index_grouped_by_label.py) that parses all issues in a GitLab project by labels, and creates or updates a Markdown index file in the same repository. The issues are grouped by label.\n\n\nFirst, the issues are fetched from the project, including all labels, and stored in the `index` dictionary.\n\n\n```python\n\np = gl.projects.get(PROJECT_ID)\n\n\nlabels = p.labels.list()\n\n\nindex={}\n\n\nfor i in p.issues.list():\n    for l in i.labels:\n        if l not in index:\n            index[l] = []\n\n        index[l].append(\"#{id} - {title}\".format(id=i.id, title=i.title))\n```\n\n\nThe second step is to create a Markdown formatted listing based on the collected index data, with the label name as key, holding a list of issue strings.\n\n\n```python\n\nindex_str = \"\"\"# Issue Overview\n\n_Grouped by issue labels._\n\n\"\"\"\n\n\nfor l_name, i_list in index.items():\n    index_str += \"\\n## {label} \\n\\n\".format(label=l_name)\n\n    for i in i_list:\n        index_str += \"- {title}\\n\".format(title=i)\n```\n\n\nThe last step is to create a new file in the repository, or update an existing one. This is a little tricky because the API expects you to define the action and will throw an error if you try to update a nonexistent file. The first condition checks whether the file path exists in the repository, and then defines the `action` attribute. The `data` dictionary gets built, with the final `commits.create()` method called.\n\n\n```python\n\n# Dump index_str to FILE_NAME\n\n# Create as new commit\n\n# See https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions\n\n# for actions detail\n\n\n# Check if file exists, and define commit action\n\nf = p.files.get(file_path=FILE_NAME, ref=REF_NAME)\n\nif not f:\n    action='create'\nelse:\n    action='update'\n\ndata = {\n    'branch': REF_NAME,\n    'commit_message': 'Generate new index, {d}'.format(d=date.today()),\n    'actions': [\n        {\n            'action': action,\n            'file_path': FILE_NAME,\n            'content': index_str\n        }\n    ]\n}\n\n\ncommit = p.commits.create(data)\n\n```\n\n\n## Advanced DevSecOps workflows\n\n\n- [Container images to run API scripts](#container-images-to-run-api-scripts)\n\n- [CI/CD integration: Release and changelog generation](#cicd-integration-release-and-changelog-generation)\n\n- [CI/CD integration: Pipeline report summaries](#cicd-integration-pipeline-report-summaries)\n\n\n### Container images to run API scripts\n\n\nInstalling the Python interpreter and dependent libraries into the operating system may not always work, or it may be a barrier to using the API scripts. A container image that can be pulled from the GitLab registry is a good first step towards more DevSecOps automation and future CI/CD integrations, and provides a tested environment. The python-gitlab project [provides container images](https://python-gitlab.readthedocs.io/en/stable/index.html#using-the-docker-images) which can be used for testing.\n\n\nThe cloned script repository can be mounted into the container, and the settings are configured using environment variables. Example with Docker CLI:\n\n\n```shell\n\n$ docker run -ti -v \"`pwd`:/app\" \\\n  -e \"GL_SERVER=http://gitlab.com\" \\\n  -e \"GL_TOKEN=$GITLAB_TOKEN\" \\\n  -e \"GL_GROUP_ID=16058698\" \\\nregistry.gitlab.com/python-gitlab/python-gitlab:slim-bullseye \\\n\npython /app/python_gitlab_manageable_objects.py\n\n```\n\n\n### CI/CD integration: Release and changelog generation\n\n\nCreating a Git tag and a release in GitLab often requires a changelog attached. This provides a summary into all Git commits, all merged merge requests, or something similar that is easier to consume for everyone interested in the changes in this new release. Automating the changelog generation in CI/CD pipelines is possible using the GitLab API. The simplest list uses the Git commit history shown in the [`create_simple_changelog_from_git_history.py`](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/create_simple_changelog_from_git_history.py) script below:\n\n\n\n```python\n\nproject = gl.projects.get(PROJECT_ID)\n\ncommits = project.commits.list(ref_name='main', lazy=True, iterator=True)\n\n\nprint(\"# Changelog\")\n\n\nfor commit in commits:\n    # Generate a markdown formatted list with URLs\n    print(\"- [{text}]({url}) ({name})\".format(text=commit.title, url=commit.web_url, name=commit.author_name))\n```\n\n\nExecuting the script on the [o11y.love project](https://gitlab.com/everyonecancontribute/observability/o11y.love) will print a Markdown list with URLs.\n\n\n```shell\n\n$ python3 create_changelog_from_git_history.py\n\n# Changelog\n\n- [Merge branch 'topics-ebpf-opentelemetry' into 'main'](https://gitlab.com/everyonecancontribute/observability/o11y.love/-/commit/75df97e13e0f429803dc451aac7fee080a51f44c) (Michael Friedrich)\n\n- [Move eBPF/OpenTelemetry into dedicated topics pages ](https://gitlab.com/everyonecancontribute/observability/o11y.love/-/commit/8fa4233630ff8c1d65aff589bd31c4c2f5df36cb) (Michael Friedrich)\n\n- [Merge branch 'workshop-add-k8s-o11y-toc' into 'main'](https://gitlab.com/everyonecancontribute/observability/o11y.love/-/commit/8b7949b19af6aa6bf25f73ca1ffe8616a7dbaa00) (Michael Friedrich)\n\n- [Add TOC for Kubesimplify Kubernetes Observability workshop ](https://gitlab.com/everyonecancontribute/observability/o11y.love/-/commit/63c8ad587f43e3926e6749a62c33ad0b6f229f47) (Michael Friedrich)\n\n\n...\n\n```\n\n\n**Exercise**: The script is not production ready yet but should get you going to group by commits by Git tag/release, filter merge commits, attach the changelog file or content into the [GitLab release details](https://docs.gitlab.com/ee/api/releases/), etc.\n\n\n### CI/CD integration: Pipeline report summaries\n\n\nWhen developing new API script in Python, a CI/CD integration with automated runs can be desired, too. My recommendation is to focus on writing and testing the script stand-alone on the command line first, and once it works reliably, adapt the code to run the script to perform actions in CI/CD, too. After writing a few scripts, and practicing a lot, you will have learned to write code that can be executed on the CLI, in containers and in CI/CD jobs.\n\n\nA good preparation for CI/CD is to focus on environment variables to configure the script. The environment variables can be defined as CI/CD variables, and there is no extra work with additional configuration files, or command line parameters involved. This keeps the CI/CD configuration footprint small and reusable, too.\n\n\nAn example integration to automatically create security summaries as markdown comment in a merge request was described in the [\"Fantastic Infrastructure-as-Code security attacks and how to find them\" blog post](/blog/fantastic-infrastructure-as-code-security-attacks-and-how-to-find-them/#integrations-into-cicd-and-merge-requests-for-review). This use case required research and testing before actually writing the full API script:\n\n\n1. Read the python-gitlab documentation to learn how [merge request comments (notes)](https://python-gitlab.readthedocs.io/en/stable/gl_objects/notes.html#project-notes) can be created.\n\n2. Create a test project and a test merge request for testing.\n\n3. Start writing code which instantiates the GitLab connection object, fetches the project object, and gets the merge request object from a pre-defined ID.\n\n4. Run `mr.notes.create({‘body’: ‘This is a test by dnsmichi’})`\n\n5. Iterate on the body content and pre-fill a string with a markdown table.\n\n6. Fetch pre-defined CI/CD variables to get the `CI_MERGE_REQUEST_ID` value which will be required to update as target.\n\n6. Verify the API permissions and learn that the CI job token is not sufficient.\n\n7. Implement the full algorithm, integrated CI/CD testing and add documentation.\n\n\nThe script runs continuously after security scans have been completed with a report. Another use case can be using [Pipeline schedules](https://docs.gitlab.com/ee/ci/pipelines/schedules.html) which provide synchronization capabilities, and the comments get posted to an issue summary.\n\n\n## Development tips\n\n\nCode and abstraction libraries are helpful but sometimes it can be hard to see the problem why an attribute or object does not provide the expected behavior. It is helpful to take a step back, and look into different ways to fetch data from the REST API, for example [using jq and curl](/blog/devops-workflows-json-format-jq-ci-cd-lint/). The [GitLab CLI](/blog/introducing-the-gitlab-cli/) can also be used to query the API and get immediate results.\n\n\nDeveloping scripts that interact with APIs can become a repetitive task, adding more needed attributes, and the need to learn about object relations, methods and how to store the retrieved data. Especially for larger datasets, it can be a good idea to use the JSON library to dump data structures into a file cache on disk, and provide a debug configuration option to read the data from that file, instead of firing the API requests again all the time. This also helps to mitigate potential rate limiting.\n\n\nAdding timing points to the code can help measure the performance, and efficiency of the algorithm used. The following snippet [measures the duration](https://stackoverflow.com/questions/7370801/how-do-i-measure-elapsed-time-in-python ) of requests to retrieve the merge request status. It is part of a script that was used to analyze a potential problem with the `detailed_merge_status` attribute in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/386661#note_1237757295).\n\n\n```\n\nmrs = project.mergerequests.list(state='opened', iterator=True, with_merge_status_recheck=True)\n\n\nfor mr in mrs:\n    start = timer()\n    #print(mr.attributes) #debug\n    # https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-request-diffs\n    real_mr = project.mergerequests.get(mr.get_id())\n\n    print(\"- [ ] !{mr_id} - {mr_url}+ Status: {s}, Title: {t}\".format(\n        mr_id=real_mr.attributes['iid'],\n        mr_url=real_mr.attributes['web_url'],\n        s=real_mr.attributes['detailed_merge_status'],\n        t=real_mr.attributes['title']))\n\n    end = timer()\n    duration = end - start\n    if duration > 1.0:\n        print(\"ALERT: > 1s \")\n    print(\"> Execution time took {s}s\".format(s=(duration)))\n```\n\n\nMore tips are discussed in the following sections:\n\n\n- [Advanced custom configuration](#advanced-custom-configuration)\n\n- [CI/CD code linting for different Python versions](#cicd-code-linting-for-different-python-versions)\n\n\n### Advanced custom configuration\n\n\nWhen you are developing a script that requires advanced custom configuration, choose a format that fits best into existing infrastructure and development guidelines. Python provides libraries for parsing YAML, JSON, etc. The following example configuration file and script showcase a YAML configuration option. It is based on [a script that automatically updates a list of issues/epics](https://gitlab.com/gitlab-de/gitlab-api-automated-commenter) with a comment, reminding responsible team members for a recurring update for a cross-functional initiative at GitLab.\n\n\n[python_gitlab_custom_yaml_config.yml](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/python_gitlab_custom_yaml_config.yml)\n\n```yaml\n\ntasks:\n  - name: \"Backend\"\n    url: \"https://gitlab.com/group1/project2/-/issues/1\"\n  - name: \"Frontend\"\n    url: \"https://gitlab.com/group2/project4/-/issues/2\"\n```\n\n\n[python_gitlab_custom_script_config_yaml.py](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/python_gitlab_custom_script_config_yaml.py)\n\n```python\n\nimport os\n\nimport yaml\n\n\nCONFIG_FILE = os.environ.get('GL_CONFIG_FILE', \"python_gitlab_custom_yaml_config.yml\")\n\n\n# Read config\n\nwith open(CONFIG_FILE, mode=\"rt\", encoding=\"utf-8\") as file:\n    config = yaml.safe_load(file)\n    #print(config) #debug\n\ntasks = []\n\nif \"tasks\" in config:\n    tasks = config['tasks']\n\n# Process the tasks\n\nfor task in tasks:\n    print(\"Task name: '{n}' Issue URL to update: {id}\".format(n=task['name'], id=task['url']))\n    # print(task) #debug\n```\n\n\n```shell\n\n$ python3 python_gitlab_custom_script_config_yaml.py                                     ─╯\n\nTask name: 'Backend' Issue URL to update: https://gitlab.com/group1/project2/-/issues/1\n\nTask name: 'Frontend' Issue URL to update: https://gitlab.com/group2/project4/-/issues/2\n\n```\n\n\n\n### CI/CD code linting for different Python versions\n\n\nAll code examples in this blog post have been tested with Python 3.8, 3.9, 3.10 and 3.11, using [parallel matrix builds in GitLab CI/CD](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/.gitlab-ci.yml) and pyflakes for code linting. Automating the tests helps focus on development, and ensuring that the target platforms support the language features. Some Linux distributions do not provide Python 3.11 yet for example, and Python language features cannot be used or may need an alternative implementation.\n\n\n```yaml\n\ninclude:\n  - template: Security/SAST.gitlab-ci.yml\n  - template: Dependency-Scanning.gitlab-ci.yml\n  - template: Secret-Detection.gitlab-ci.yml\n\nstages:\n  - lint\n  - test\n\n.python-req:\n  image: python:$VERSION\n  script:\n    - pip install -r requirements_dev.txt\n  parallel:\n    matrix:\n      - VERSION: ['3.8', '3.9', '3.10', '3.11']   # https://hub.docker.com/_/python\n\nlint-python:\n  extends: .python-req\n  stage: lint\n  script:\n    - !reference [.python-req, script]\n    - pyflakes .\n\nsast:\n  stage: test\n\n```\n\n\n## Optimize code and performance\n\n\n- [Lazy objects](#lazy-objects)\n\n- [Object-oriented programming](#object-oriented-programming)\n\n\n### Lazy objects\n\n\nWhen working with objects that do not immediately need all attributes loaded, you can specify the [`lazy=True`](https://python-gitlab.readthedocs.io/en/stable/api-usage.html#lazy-objects) attribute to not invoke an API call immediately. A follow-up method call will then invoke the required API calls.\n\n\n\n```python\n\n# Lazy object, no API call\n\nproject = gl.projects.get(PROJECT_ID, lazy=True)\n\n\ntry:\n    print(\"Trying to access 'snippets_enabled' on a lazy loaded project object. This will throw an exception that we capture.\")\n    print(\"Project settings: snippets_enabled={b}\".format(b=project.snippets_enabled))\nexcept Exception as e:\n    print(\"Accessing lazy loaded object failed: {e}\".format(e=e))\n\nproject.snippets_enabled = True\n\n\nproject.save() # This creates an API call\n\n\nprint(\"\\nLazy object was loaded after save() call.\")\n\nprint(\"Project settings: snippets_enabled={b}\".format(b=project.snippets_enabled))\n\n\n```\n\n\nExecuting the [`python_gitlab_lazy_objects.py`](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/python_gitlab_lazy_objects.py) script shows that the lazy object did not fire an API call, thus throwing an exception when accessing the project setting `snippets_enabled`. To show that the object still can be managed, the code catches the exception to proceed with updating the setting locally, and calling `project.save()` to persist the change and call the API update.\n\n\n```shell\n\n$ python3 python_gitlab_lazy_objects.py                                                ─╯\n\nTrying to access 'snippets_enabled' on a lazy loaded project object. This will throw an exception that we capture.\n\nAccessing lazy loaded object failed: 'Project' object has no attribute 'snippets_enabled'\n\n\nIf you tried to access object attributes returned from the server,\n\nnote that \u003Cclass 'gitlab.v4.objects.projects.Project'> was created as\n\na `lazy` object and was not initialized with any data.\n\n\nLazy object was loaded after save() call.\n\nProject settings: snippets_enabled=True\n\n```\n\n\n### Object-oriented programming\n\n\nFor better code quality, it makes sense to follow object-oriented programming and create classes that store attributes, provide methods, and enable better unit testing. The [storage analyzer tool](https://gitlab.com/gitlab-de/gitlab-storage-analyzer) was developed to create a summary of projects that consume lots storage, for example CI/CD job artifacts. By inspecting the [Git history](https://gitlab.com/gitlab-de/gitlab-storage-analyzer/-/commits/main), you can learn from the different iterations to a first working version.\n\n\nThe following example is a trimmed version which shows how to initialize the class `GitLabUseCase`, add helper functions for logging and JSON pretty-printing, and print all project attributes.\n\n\n```python\n\n#!/usr/bin/env python\n\n\nimport gitlab\n\nimport os\n\nimport sys\n\nimport json\n\n\n# Print an error message with prefix, and exit immediately with an error code.\n\ndef error(text):\n    logger(\"ERROR\", text)\n    sys.exit(1)\n\n# Log a line with a given prefix (e.g. INFO)\n\ndef logger(prefix, text):\n    print(\"{prefix}: {text}\".format(prefix=prefix, text=text))\n\n# Return a pretty-printed JSON string with indent of 4 spaces\n\ndef render_json_output(data):\n    return json.dumps(data, indent=4, sort_keys=True)\n\n# Class definition\n\nclass GitLabUseCase(object):\n    # Initializer to set all required parameters\n    def __init__(self, verbose, gl_server, gl_token, gl_project_id):\n        self.verbose = verbose\n        self.gl_server = gl_server\n        self.gl_token = gl_token\n        self.gl_project_id = gl_project_id\n\n    # Debug logger, controlled via verbose parameter\n    def log_debug(self, text):\n        if self.verbose:\n            print(\"DEBUG: {d}\".format(d=text))\n\n    # Connect to the GitLab server and store the connection handle\n    def connect(self):\n        self.log_debug(\"Connecting to GitLab API at {s}\".format(s=self.gl_server))\n        # Supports personal/project/group access token\n        # https://docs.gitlab.com/ee/api/index.html#personalprojectgroup-access-tokens\n        self.gl = gitlab.Gitlab(self.gl_server, private_token=self.gl_token)\n\n    # Use the stored connection handle to fetch a project object by id,\n    # and print its attribute with JSON pretty-print.\n    def print_project_attributes(self):\n        project = self.gl.projects.get(self.gl_project_id)\n        print(render_json_output(project.attributes))\n\n\n## main\n\nif __name__ == '__main__':\n    # Fetch configuration from environment variables.\n    # The second parameter specifies the default value when not provided.\n    gl_verbose = os.environ.get('GL_VERBOSE', False)\n    gl_server = os.environ.get('GL_SERVER', 'https://gitlab.com')\n\n    gl_token = os.environ.get('GL_TOKEN')\n\n    if not gl_token:\n        error(\"Please specifiy the GL_TOKEN env variable\")\n\n    gl_project_id = os.environ.get('GL_PROJECT_ID', 42491852) # https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python\n\n    # Instantiate new object and run methods\n    gl_use_case = GitLabUseCase(gl_verbose, gl_server, gl_token, gl_project_id)\n    gl_use_case.connect()\n    gl_use_case.print_project_attributes()\n```\n\n\nRunning the [script](https://gitlab.com/gitlab-de/use-cases/gitlab-api/gitlab-api-python/-/blob/main/python_gitlab_oop_helpers.py) with the `GL_PROJECT_ID` environment variable pretty-prints the project attributes as JSON on the terminal.\n\n\n![Example script that pretty-prints the project object attributes as JSON](/images/blogimages/efficient-devsecops-workflows-python-gitlab-handson/python_gitlab_oop_example_terminal_output_project_attributes.png){: .shadow}\n\n\n## More use cases\n\n\nBetter performance with API requests can be achieved by looking into parallelization and threading in Python. Users have been testing the storage analyzer script, and provided feedback to optimize the performance for the single-threaded script by using tasks and [Python threading](https://realpython.com/intro-to-python-threading/), similar to [this community project](https://gitlab.com/thelabnyc/gitlab-storage-cleanup). I might follow up on this topic in a future blog post, there are many more great use cases to cover using python-gitlab.\n\n\nThere is so much more to learn, here are a few examples from the GitLab community forum that could not make it into this blog post:\n\n\n* [Fetch review app environment URL from Merge Request](https://forum.gitlab.com/t/fetch-review-app-environment-url-from-merge-request/71335/2)\n\n* [Project visibility, project features, permissions](https://forum.gitlab.com/t/project-visibility-project-features-permissions-settings-api/32242)\n\n* [Download GitLab CI/CD job artifacts using Python](https://forum.gitlab.com/t/download-gitlab-ci-jobs-artifacts-using-python/25436/$)\n\n\n## Conclusion\n\n\nThe python-gitlab library helps to abstract raw REST API calls, and to keep access to attributes, functions and objects short and relatively easy. There are many use cases that can be solved efficiently. Alternative programming language libraries for the GitLab REST API are available [in the API clients section here](/partners/technology-partners/#api-clients).\n\n\nThe [GitLab Community Forum](https://forum.gitlab.com/) is a great place to collaborate on use cases and questions about possible solutions or code snippets. We'd love to hear from you about your use cases and challenges using the python-gitlab library.\n\n\nShoutout to the python-gitlab maintainers and contributors, developing this fantastic API library for many years now! If this blog post and the python-gitlab library helped you get more efficient, please consider [contributing to python-gitlab](https://python-gitlab.readthedocs.io/en/stable/#contributing). When there is a GitLab API feature missing, look into [contributing to GitLab](https://about.gitlab.com/community/contribute/), too. Thank you!\n\n\n\nCover image by [David Clode](https://unsplash.com/@davidclode) on [Unsplash](https://unsplash.com/photos/cxMJYcuCLEA)\n\n{: .note}\n",[233,827,9,496],{"slug":1439,"featured":6,"template":698},"efficient-devsecops-workflows-hands-on-python-gitlab-api-automation","content:en-us:blog:efficient-devsecops-workflows-hands-on-python-gitlab-api-automation.yml","Efficient Devsecops Workflows Hands On Python Gitlab Api Automation","en-us/blog/efficient-devsecops-workflows-hands-on-python-gitlab-api-automation.yml","en-us/blog/efficient-devsecops-workflows-hands-on-python-gitlab-api-automation",{"_path":1445,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1446,"content":1452,"config":1459,"_id":1461,"_type":14,"title":1462,"_source":16,"_file":1463,"_stem":1464,"_extension":19},"/en-us/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines",{"title":1447,"description":1448,"ogTitle":1447,"ogDescription":1448,"noIndex":6,"ogImage":1449,"ogUrl":1450,"ogSiteName":686,"ogType":687,"canonicalUrls":1450,"schema":1451},"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","\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":1453,"description":1448,"authors":1454,"heroImage":1449,"date":1456,"body":1457,"category":909,"tags":1458},"How to create efficient DevSecOps workflows with rules for conditional CI/CD pipelines",[1455],"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",[827,825,826,9,496],{"slug":1460,"featured":6,"template":698},"efficient-devsecops-workflows-with-rules-for-conditional-pipelines","content:en-us:blog:efficient-devsecops-workflows-with-rules-for-conditional-pipelines.yml","Efficient Devsecops Workflows With Rules For Conditional Pipelines","en-us/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines.yml","en-us/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines",{"_path":1466,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1467,"content":1473,"config":1479,"_id":1481,"_type":14,"title":1482,"_source":16,"_file":1483,"_stem":1484,"_extension":19},"/en-us/blog/eliminate-risk-with-feature-flags-tutorial",{"title":1468,"description":1469,"ogTitle":1468,"ogDescription":1469,"noIndex":6,"ogImage":1470,"ogUrl":1471,"ogSiteName":686,"ogType":687,"canonicalUrls":1471,"schema":1472},"How to use feature flags to lower risk in deployments","Follow this comprehensive tutorial to learn how to create and use feature flags in your software development environment.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749667743/Blog/Hero%20Images/flags.png","https://about.gitlab.com/blog/eliminate-risk-with-feature-flags-tutorial","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to use feature flags to lower risk in deployments\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Cesar Saavedra\"}],\n        \"datePublished\": \"2023-09-20\",\n      }",{"title":1468,"description":1469,"authors":1474,"heroImage":1470,"date":1476,"body":1477,"category":10,"tags":1478},[1475],"Cesar Saavedra","2023-09-20","Developers typically use advanced techniques like canary, blue/green, and\nincremental deployments to reduce risk when practicing progressive delivery,\na facet of continuous delivery (CD). In this tutorial, we will show you how\nto use feature flags, another progressive delivery option developers can use\nto test while in production.\n\n\n## What is progressive delivery?\n\nProgressive delivery is the ability to test in production while controlling\nyour audience of who can exercise or see updates to an application with a\nhigh level of granularity. This approach can also be thought of as developer\nexperimentation.\n\n\n## What are feature flags\n\nFeature flags enable you to choose what to deploy and who to deploy to in\nproduction. They allow you to define the audience for your application\nupdates as well as the fashion in which they will be served.\n\n\nFeature flags help stakeholders reduce risk, allowing them to do controlled\ntesting of features and separate feature delivery from customer launch.\n\n\n## Benefits of feature flags\n\nThe following are benefits of GitLab's feature flags.\n\n- **Lower risk.** Feature flags prevent unscheduled outages, control your\naudience in a fine-grained fashion, and can be optionally used in\nconjunction with canary deployments.\n\n- **Ease of use.** Feature flags have simple configurability and\ninstrumentation, support user lists, and offer built-in service.\n\n- **Language agnostic.** Our feature flag implementation supports all of the\nmain programming languages.\n\n- **Better compliance and audit capabilities.** The GitLab platform\nautomatically records all feature flags actions.\n\n\n## Tutorial requirements\n\nThis is what you need for this tutorial:\n\n1. A GitLab account on gitlab.com SaaS\n\n2. Flux CLI installed on your local desktop (on my Mac, I installed it by\nexecuting `brew install fluxcd/tap/flux`)\n\n3. A running Kubernetes cluster, i.e. a GKE cluster with 3 e2-medium nodes\n\n4. `kubectl` connectivity to your Kubernetes cluster from a local Terminal\nwindow on your desktop\n\n\n## About this feature flag tutorial\n\nThis tutorial is based on a fictitious application, which is a simplified\ninventory system. The goal of this tutorial is to show you how to create,\nconfigure, and implement a feature flag using GitLab.\n\n\n**Note:** This tutorial is for learning purposes and not meant to deploy a\nproduction-ready architecture. Also, to keep the number of steps low, masked\nvariables and sealed secrets are not being used throughout this tutorial.\n\n\n## Flux and the GitLab agent for Kubernetes\n\nHere is how to install Flux and GitLab agent for Kubernetes.\n\n- Log on to your GitLab workspace.\n\n- Create a personal access token (PAT) from your GitLab account by\nnavigating to **User settings > Preferences > Access tokens**. In the\n**Personal Access Tokens** section, click on the **Add new token** button on\nthe righthand side of the section. For **Token name**, enter `pat-for-flux`.\nLeave the expiration date with its default (it should be 30 days from its\ncreation) and select the **API** scope for your **PAT**. Click on the\n**Create personal access token** button to create your PAT. Copy and save\nthe value of your **PAT**; you will need it at a later step.\n\n\n![create-pat](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/create-pat.png){:\n.shadow.medium.center}\n\nCreating a personal access token\n\n{: .note.text-center}\n\n\n- Head back to your GitLab workspace main page.\n\n- Create a group named “hn” by clicking the button **New group** (or **New\nsubgroup** if you are creating this group inside an existing group) on the\ntop right hand side of your screen, and then clicking on the **Create\ngroup** tile. Enter \"hn\" for your **Group name** and click on the **Create\ngroup** button to create it. Leave the rest of the fields with their\ndefaults.\n\n\n![create-group-hn](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/create-group-hn.png){:\n.shadow.medium.center}\n\nCreating group \"hn\"\n\n{: .note.text-center}\n\n\n- Inside group “hn”, create project “flux-config” by clicking the **New\nproject** on the top righthand side of your screen and then clicking on the\n**Create blank project** tile.\n\n\n![create-proj-flux-config](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/create-proj-flux-config.png){:\n.shadow.medium.center}\n\nCreating project \"flux-config\"\n\n{: .note.text-center}\n\n\n- From the Terminal window with `kubectl` access to your Kubernetes cluster,\nexport your **PAT** by entering the following command:\n\n\n> export GITLAB_TOKEN=`\u003Creplace with your PAT value>`\n\n\n- From the Terminal window with `kubectl` access to your Kubernetes cluster,\nbootstrap Flux by executing the following command:\n\n\n**Note:** Make sure to replace `\u003Cyour path>` with whatever precedes your\ngroup “hn”. For example, it could be `--owner=tech-marketing/sandbox/hn`, or\nif your group “hn” is at the very top level of your GitLab workspace, it\nwould be `--owner=hn`.\n\n\n```\n\nflux bootstrap gitlab \\\n  --owner=\u003Cyour path>/hn \\\n  --repository=flux-config \\\n  --branch=main \\\n  --path=clusters/my-cluster \\\n  --deploy-token-auth\n```\n\n\n![flux-bootstrap-output](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/flux-bootstrap-output.png){:\n.shadow.medium.center.}\n\nFlux bootstrap output\n\n{: .note.text-center}\n\n\nThe “flux-config” project should now contain new directories and files as\nshown below:\n\n\n![flux-config-post-bootstrap](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/flux-config-post-bootstrap.png){:\n.shadow.medium.center}\n\nProject flux-config post flux bootstrap process\n\n{: .note.text-center}\n\n\n- Head over to project **hn/flux-config** and create file\n“.gitlab/agents/k8s-agent/config.yaml” by clicking on the **+** sign next to\nthe “flux-config” and selecting **New file**. Paste the following into it\nthe new file:\n\n\n**Note:** Make sure to replace `\u003Cyour path>` with whatever precedes your\ngroup “hn”. For example, it could be `- id: tech-marketing/sandbox/hn` or if\nyour group “hn” is at the very top level of your GitLab workspace, it would\nbe `- id: hn`.\n\n\n```\n\nci_access:\n  groups:\n    - id: \u003Cyour path>/hn\n```\n\n\nCommit this file to main by clicking on the **Commit changes** button and\nensuring that the target branch is “main”.\n\n\n![create-config-yaml](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/create-config-yaml.png){:\n.shadow.medium.center}\n\nCreating the GitLab agent for Kubernetes configuration manifest\n\n{: .note.text-center}\n\n\n- Head to **Operate > Kubernetes clusters** and register the agent by\nclicking the **Connect a cluster** button.\n\n\n![register-agent](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/register-agent.png){:\n.shadow.medium.center}\n\nRegistering the GitLab agent for Kubernetes\n\n{: .note.text-center}\n\n\n- On the “Connect a Kubernetes cluster” dialog, click on the popdown list\nand select agent “k8s-agent”. Click on the **Register** button. The dialog\nwill refresh and show the **Agent access token**. Copy and save the **Agent\naccess token**; you will need it at a later step. Close the dialog by\nclicking on the **Close** button.\n\n\n![agent-access-token-dialog](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/agent-access-token-dialog.png){:\n.shadow.medium.center}\n\nThe agent access token to save\n\n{: .note.text-center}\n\n\nAt this moment, you will see the agent listed and its Connection status will\nbe “Never connected”.\n\n\n![agent-not-connected](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/agent-not-connected.png){:\n.shadow.medium.center}\n\nAgent registered but not connected yet\n\n{: .note.text-center}\n\n\n-  Head to **flux-config/clusters/my-cluster** directory and create a file\nnamed “namespace-gitlab.yaml” and paste the following into it:\n\n\n```\n\napiVersion: v1\n\nkind: Namespace\n\nmetadata:\n  name: gitlab\n```\n\n\n![gitlab-namespace-manifest](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/gitlab-namespace-manifest.png){:\n.shadow.medium.center}\n\nManifest for the gitlab namespace\n\n{: .note.text-center}\n\n\nCommit this file to main by clicking on the **Commit changes** button and\nensuring that the target branch is “main”.\n\n\n```\n\nNote: You can check that the namespace was created in your cluster by\nexecuting this command from a Terminal:\n\n\nkubectl get ns\n\n```\n\n\n![gitlab-ns-created](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/gitlab-ns-created.png){:\n.shadow.medium.center}\n\nFlux created gitlab namespace\n\n{: .note.text-center}\n\n\n- Before we have Flux deploy the GitLab agent for Kubernetes to your\ncluster, we need to create a secret, containing the **Agent access token**\nyou saved earlier, in your cluster. Create a file named “secret.yaml” in\nyour local desktop, paste the following into it and then save it:\n\n\n**Note:** Make sure to replace `\u003Cyour-agent-access-token-here>` with your\n**Agent access token** you saved earlier.\n\n\n```\n\napiVersion: v1\n\nkind: Secret\n\nmetadata:\n  name: gitlab-agent-token-initial\ntype: Opaque\n\nstringData:\n  values.yaml: |-\n    config:\n      token: \"\u003Cyour-agent-access-token-here>\"\n```\n\n\n![agent-token-secret](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/agent-token-secret.png){:\n.shadow.medium.center.}\n\nManifest for agent token secret created on local desktop\n\n{: .note.text-center}\n\n\n- Create the secret in your cluster by executing the following command from\na Terminal:\n\n\n> kubectl apply -f secret.yaml -n gitlab\n\n\n```\n\nNote: You can check that the secret was created in your cluster by executing\nthis command from a Terminal:\n\n\nkubectl get secrets -n gitlab\n\n```\n\n\n![apply-agent-token-secret](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/apply-agent-token-secret.png){:\n.shadow.medium.center}\n\nApplying the agent token secret to the Kubernetes cluster\n\n{: .note.text-center}\n\n\n- Now let’s use the Flux Helm Controller to deploy the GitLab agent for\nKubernetes to your cluster. Head to **flux-config/clusters/my-cluster**\ndirectory and create a file named “agentk.yaml” and paste the following into\nit:\n\n\n```\n\n---\n\napiVersion: source.toolkit.fluxcd.io/v1beta2\n\nkind: HelmRepository\n\nmetadata:\n  labels:\n    app.kubernetes.io/component: agentk\n    app.kubernetes.io/created-by: gitlab\n    app.kubernetes.io/name: agentk\n    app.kubernetes.io/part-of: gitlab\n  name: gitlab-agent\n  namespace: gitlab\nspec:\n  interval: 1h0m0s\n  url: https://charts.gitlab.io\n---\n\napiVersion: helm.toolkit.fluxcd.io/v2beta1\n\nkind: HelmRelease\n\nmetadata:\n  name: gitlab-agent\n  namespace: gitlab\nspec:\n  chart:\n    spec:\n      chart: gitlab-agent\n      sourceRef:\n        kind: HelmRepository\n        name: gitlab-agent\n        namespace: gitlab\n  interval: 1h0m0s\n  values:\n    replicas: 1\n    config:\n      kasAddress: \"wss://kas.gitlab.com\"  \n  valuesFrom:\n    - kind: Secret\n      name: gitlab-agent-token-initial\n      valuesKey: values.yaml\n```\n\n\n![create-agentk-manifest](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/create-agentk-manifest.png){:\n.shadow.medium.center}\n\nCreating the manifest for the GitLab agent for Kubernetes\n\n{: .note.text-center}\n\n\nCommit this file to main by clicking on the **Commit changes** button and\nensuring that the target branch is “main”.\n\n\n```\n\nNote: In a few seconds, you can check that the GitLab agent for Kubernetes\nwas created in your cluster by executing this command from a Terminal (the\npod name should start with “gitlab-agent”):\n\n\nkubectl get pods -n gitlab\n\n```\n\n![agentk-pod-up](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/agentk-pod-up.png){:\n.shadow.medium.center}\n\nAgentk running in the Kubernetes cluster\n\n{: .note.text-center}\n\n\n## Creating an instance of MySQL database in your cluster via Flux\n\n- Using the breadcrumb at the top of your window, head to group “hn” and\ncreate a new project by clicking on the **New project** button. On the\n**Create new project** window, click on the **Import project** tile.\n\n- At the **Import project** window, click on the **Repository by URL**\nbutton. The window will display fields to enter the URL of the repository\nyou would like to import. In the text field **Git repository URL**, enter\nthe following:\n\n\n>\n[https://gitlab.com/tech-marketing/sandbox/mysql.git](https://gitlab.com/tech-marketing/sandbox/mysql.git)\n\n\nLeave the rest of the fields with their defaults.\n\n\n![import-mysql-proj](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/import-mysql-proj.png){:\n.shadow.medium.center}\n\nImporting mysql project into group \"hn\"\n\n{: .note.text-center}\n\n\n- Click on the **Create project** button at the bottom of the screen. You\nwill see an \"Importing in progress\" message temporarily on your screen.\n\n- Now we need to create a deploy token for this project so that Flux can\ninteract with it. While in project “mysql”, select **Settings > Repository**\nand scroll down to the **Deploy tokens** section. Click on the **Expand**\nbutton to the right of the **Deploy tokens** section. Then click on the\n**Add token** button, which will expand the section to include fields to\nstart entering information for the deploy token to be created.\n\n- Give the deploy token the name “mysql-flux-deploy-token” and check the\ncheckbox **read_repository** for it. Then click on the button **Create\ndeploy token** to create the token.\n\n\n![create-mysql-deploy-token](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/create-mysql-deploy-token.png){:\n.shadow.medium.center}\n\nCreating the deploy token for \"mysql\" project for Flux to interact with it\n\n{: .note.text-center}\n\n\nCopy and save the username and password for the newly created deploy token;\nyou will need them at a later step.\n\n\n![mysql-deploy-token-created](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/mysql-deploy-token-created.png){:\n.shadow.medium.center}\n\nCreating the deploy token for \"mysql\" project for Flux to interact with it\n\n{: .note.text-center}\n\n\n-  From a Terminal, execute the following command to create a secret in your\ncluster for the deploy token you just created:\n\n\n**Note:** Make sure to replace `\u003Cyour path>` with the missing partial path\nto the project “mysql”, \u003Cyour-deploy-token-username> with the deploy token\nusername you saved earlier, and the \u003Cyour-deploy-token-password> with the\ndeploy token password you saved earlier.\n\n\n```\n\nflux create secret git mysql-flux-deploy-authentication \\\n         --url=https://gitlab.com/\u003Cyour path>/hn/mysql \\\n         --namespace=default \\\n         --username=\u003Cyour-deploy-token-username> \\\n         --password=\u003Cyour-deploy-token-password>\n```\n\n\n```\n\nNote: You can check that the secret was created in your cluster by executing\nthis command from a Terminal:\n\n\nkubectl -n default get secrets mysql-flux-deploy-authentication\n\n```\n\n\n![mysql-secret-created](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/mysql-secret-created.png){:\n.shadow.medium.center}\n\nCreating secret for the deploy token for \"mysql\" project in the Kubernetes\ncluster\n\n{: .note.text-center}\n\n\n- Head back to project “hn/flux-config” and open the Web IDE from it.\n\n\n![open-web-ide](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/open-web-ide.png){:\n.shadow.medium.center}\n\nSelecting Web IDE from the dropdown menu\n\n{: .note.text-center}\n\n\n- From inside the Web IDE, navigate to directory \"clusters/my-cluster\".\n\n\n![goto-clusters-mycluster](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/goto-clusters-mycluster.png){:\n.shadow.medium.center}\n\nNavigate to directory \"clusters/my-cluster\" in the Web IDE\n\n{: .note.text-center}\n\n\n- Inside “clusters/my-cluster” directory, create file\n“mysql-manifests-source.yaml” and paste the following text into it:\n\n\n**Note:** Replace `\u003Cyour path>` with the missing partial path to the project\n“mysql”\n\n\n```\n\napiVersion: source.toolkit.fluxcd.io/v1beta2\n\nkind: GitRepository\n\nmetadata:\n  name: mysql\n  namespace: default\nspec:\n  interval: 1m0s\n  ref:\n    branch: main\n  secretRef:\n    name: mysql-flux-deploy-authentication\n  url: https://gitlab.com/\u003Cyour path>/hn/mysql\n```\n\n\n![create-mysql-source-manifest](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/create-mysql-source-manifest.png){:\n.shadow.medium.center}\n\nCreating mysql-manifests-source.yaml file in the Web IDE\n\n{: .note.text-center}\n\n\n- Still in the Web IDE, inside “clusters/my-cluster” directory, create file\n“mysql-manifests-kustomization.yaml” and paste the following text into it:\n\n\n```\n\napiVersion: kustomize.toolkit.fluxcd.io/v1beta2\n\nkind: Kustomization\n\nmetadata:\n  name: mysql-source-kustomization\n  namespace: default\nspec:\n  interval: 1m0s\n  path: ./\n  prune: true\n  sourceRef:\n    kind: GitRepository\n    name: mysql\n    namespace: default\n  targetNamespace: default\n```\n\n\n![create-mysql-kustomization-manifest](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/create-mysql-kustomization-manifest.png){:\n.shadow.medium.center}\n\nCreating mysql-manifests-kustomization.yaml file in the Web IDE\n\n{: .note.text-center}\n\n\n- From the Web IDE, commit both files to the main branch by clicking on the\n**Source Control** icon on the left vertical menu, pressing the **Commit to\nmain** button.\n\n\n![commit-to-main](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/commit-to-main.png){:\n.shadow.medium.center}\n\nClicking on the Source Control icon and committing to main in the Web IDE\n\n{: .note.text-center}\n\n\nThen press the **Continue** button to confirm that you want to commit your\nchanges to the default branch:\n\n\n![commit-to-main-continue](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/commit-to-main-continue.png){:\n.shadow.medium.center}\n\nClicking on the Source Control icon and committing to main in the Web IDE\n\n{: .note.text-center}\n\n\n- Flux will deploy MySQL to your Kubernetes cluster. You can close the Web\nIDE browser tab at this point.\n\n\n```\n\nNote: You can check that the GitLab agent for Kubernetes was created in your\ncluster by executing this command from a Terminal:\n\n\nkubectl get pods -l app=mysql\n\n\nYou can check the persistent volume by executing this command from a\nTerminal:\n\n\nkubectl describe pvc mysql-pv-claim\n\n```\n\n\n![mysql-pod-and-pv-up](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/mysql-pod-and-pv-up.png){:\n.shadow.center}\n\nVerifying that mysql pod and its associated persitent volume claim are up\nand ready\n\n{: .note.text-center}\n\n\n- Now that the MySQL pod is up and running, we need to create a database,\ntables, and indexes in it and also populate some of the tables with dummy\ndata for the inventory system. Using the breadcrumb at the top of your\nwindow, head over to the “mysql” project and select **Build > Pipelines**\nfrom the left vertical navigation menu.\n\n\n![head-to-mysql-build-pipelines](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/head-to-mysql-build-pipelines.png){:\n.shadow.medium.center}\n\nHead to \"mysql\" project and select **Build > Pipelines** from the left\nvertical navigation menu\n\n{: .note.text-center}\n\n\n- Click on the **Run pipeline** button on the top right side of the\n**Pipelines** window. This will put you on the **Run pipeline** window.\nClick on the **Run pipeline** button on the bottom left of the **Run\npipeline** window leaving the rest of the fields with its defaults.\n\n\n![run-pipeline-button](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/run-pipeline-button.png){:\n.shadow.medium.center}\n\nClicking on the **Run pipeline** button to run the project \"mysql\" pipeline\n\n{: .note.text-center}\n\n\n- At this point you will see the pipeline stage and jobs. There are two jobs\nunder the **Build** stage: **create_and_load_db** and **clear_db**.\n\n\n![mysql-pipeline](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/mysql-pipeline.png){:\n.shadow.medium.center}\n\nThe \"mysql\" pipeline and its two manual jobs\n\n{: .note.text-center}\n\n\n- Click on the Play button (the right solid arrow) next to the\n**create_and_load_db** job name. This job will create a **product** table\nand a **users** table and populate them with dummy data. It will also create\ntables and indexes needed for storing all the session-related information as\nusers log in and log out from the inventory system.\n\n\n**Note:** The **clear_db** job should only be used if you’d like to erase\nall of the database resources created by the **create_and_load_db** job. The\n**clear_db** should only be used AFTER a failed run of the\n**create_and_load_db** job.\n\n\nNow that we have the database ready to go, let’s set up the project that we\nwill use for the creation of the feature flags.\n\n\n## Creating and importing projects\n\n- Head back to group “hn” and inside of it, create a cluster management\nproject (you can call it “cluster-management”) at the same level as the\nproject you imported above. You can view this [instructional\nvideo](https://www.youtube.com/watch?v=QRR3WuwnxXE&t=200s) (up to minute\n6:09) to see how to do this. While applying the steps in the video for this\ntutorial, adjust the variables values from the video to this post as\ndescribed in the following notes:\n\n\n**Note 1:** Make sure to create and set the KUBE_CONTEXT and KUBE_NAMESPACE\nvariable in group “hn” and to these values:\n\n\n| variable | value |\n\n| ---          | ---      |\n\n| KUBE_CONTEXT | `\u003Cyour path>`/hn/flux-config:k8s-agent |\n\n| KUBE_NAMESPACE | my-apps |\n\n\nFor example, in my case `\u003Cyour path>` was\n“tech-marketing/sandbox/hn/flux-config:k8s-agent”. In your case, it will be\ndifferent. If `\u003Cyour path>` is at the root of your GitLab workspace, then it\nwould be empty so the value of KUBE_CONTEXT would be\n“hn/flux-config:k8s-agent”.\n\n\n![add-var-KUBE_CONTEXT](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/add-var-KUBE_CONTEXT.png){:\n.shadow.medium.center}\n\nAdding variable KUBE_CONTEXT in group \"hn\"\n\n{: .note.text-center}\n\n\n![add-var-KUBE_NAMESPACE](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/add-var-KUBE_NAMESPACE.png){:\n.shadow.medium.center}\n\nAdding variable KUBE_NAMESPACE in group \"hn\"\n\n{: .note.text-center}\n\n\n**Note 2:** As an FYI, when uncommenting the GitLab managed apps in the\n“helmfile.yaml” file, there will not be one for Prometheus. So, you will\nonly uncomment the lines for ingress and cert-manager.\n\n\n![uncomment-ingress-and-cert-manager](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/uncomment-ingress-and-cert-manager.png){:\n.shadow.medium.center}\n\nUncommenting lines for ingress and cert-manager in file \"helmfile.yaml\"\n\n{: .note.text-center}\n\n\n**Note 3:** When the pipeline for project “cluster-management” runs, you\nwill notice that the job “sync” is a manual job. You will need to click on\nits **Play** (right arrow next to its name) button to run it. Wait until the\n“sync” job completes successfully before continuing.\n\n\n![click-play-on-sync-job](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/click-play-on-sync-job.png){:\n.shadow.medium.center}\n\nJob \"sync\" is manual so you need to press on the **Play** button next to its\nname\n\n{: .note.text-center}\n\n\n**Note 4:** Once the pipeline finishes, for your convenience, here is the\ncommand you need to run from a Terminal window to get the **external IP**\naddress of your cluster:\n\n\n```\n\nkubectl --namespace gitlab-managed-apps get services -o wide -w\ningress-ingress-nginx-controller\n\n```\n\n\n![getting-external-ip-address](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/getting-external-ip-address.png){:\n.shadow.medium.center}\n\nRunning `kubectl` command to get the ingress IP address to the cluster\n\n{: .note.text-center}\n\n\nCreate and set a variable `KUBE_INGRESS_BASE_DOMAIN` in group “hn” and set\nit to the **external IP** address of your cluster and append the suffix\n“.nip.io” to it.\n\n\n![add-var-KUBE_INGRESS_BASE_DOMAIN](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/add-var-KUBE_INGRESS_BASE_DOMAIN.png){:\n.shadow.medium.center}\n\nAddding variable KUBE_INGRESS_BASE_DOMAIN in group \"hn\"\n\n{: .note.text-center}\n\n\n- Inside group “hn”, create a new project. Click on the **New project**\nbutton. On the **Create new project** window, click on the **Import\nproject** tile and then click on the **Repository by URL** button.\n\n- This will expand the window and show fields to enter the URL of the\nrepository you would like to import. In the field **Git repository URL**,\nenter the following:\n\n\n>\n[https://gitlab.com/tech-marketing/sandbox/prodmgr.git](https://gitlab.com/tech-marketing/sandbox/prodmgr.git)\n\n\nLeave the rest of the fields with their defaults.\n\n\n![import-prodmgr-proj](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/import-prodmgr-proj.png){:\n.shadow.medium.center}\n\nImporting project \"prodmgr\" into group \"hn\"\n\n{: .note.text-center}\n\n\n- Click on the **Create project** button at the bottom of the screen. You\nwill see an **Importing in progress** message temporarily on your screen.\n\n- In project “prodmgr”, create a pipeline file and make sure to name it\n“.gitlab-ci.yml”. Paste the following code block into the empty file:\n\n\n```\n\ninclude:\n  template: Auto-DevOps.gitlab-ci.yml\n\nvariables:\n  K8S_SECRET_TF_VAR_dbusername: \"sasha\"\n  K8S_SECRET_TF_VAR_dbpassword: \"password\"\n  TEST_DISABLED: \"true\"\n  CODE_QUALITY_DISABLED: \"true\"\n  LICENSE_MANAGEMENT_DISABLED: \"true\"\n  BROWSER_PERFORMANCE_DISABLED: \"true\"\n  LOAD_PERFORMANCE_DISABLED: \"true\"\n  SAST_DISABLED: \"true\"\n  SECRET_DETECTION_DISABLED: \"true\"\n  DEPENDENCY_SCANNING_DISABLED: \"true\"\n  CONTAINER_SCANNING_DISABLED: \"true\"\n  DAST_DISABLED: \"true\"\n  REVIEW_DISABLED: \"true\"\n  CODE_INTELLIGENCE_DISABLED: \"true\"\n  CLUSTER_IMAGE_SCANNING_DISABLED: \"true\"\n  POSTGRES_ENABLED: \"false\"\n  STAGING_ENABLED: \"true\"\n  INCREMENTAL_ROLLOUT_MODE: \"manual\"\n```\n\n\nClick on the **Commit changes** button ensuring that the **Target branch**\nis main.\n\n\n![prodmgr-proj-pipeline](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/prodmgr-proj-pipeline.png){:\n.shadow.medium.center}\n\nCreating an Auto-DevOps-based pipeline for project \"prodmgr\"\n\n{: .note.text-center}\n\n\n- The previous step builds the application and deploys it to the staging\nenvironment. Once deployed to staging, head to **Build > Pipelines** and\nclick on the most recently executed pipeline (should be the first one in the\nlist). Click on the pipeline to display it and then deploy the application\nto production by clicking on “rollout 100%” job.\n\n\n![rollout-to-prod](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/rollout-to-prod.png){:\n.shadow.medium.center}\n\nTo deploy the application to production, click on the **rollout 100%** Play\nbutton\n\n{: .note.text-center}\n\n\nAt this point, you have a running application in the staging and production\nenvironments in your Kubernetes cluster. Let’s start creating a feature\nflag.\n\n\n## Creating a new feature flag\n\n-  In project “prodmgr”, select **Deploy > Feature flags** from your left\nvertical navigation menu.\n\n\n### Creating a user list\n\n- Click on the link **View user lists** on the top right hand side of your\nscreen.\n\n- Click on the **New user list** button on the top right hand side of your\nscreen.\n\n- In the **Name** field of the user list, enter\n“prods-in-alphabetical-order-userlist” and then click on the **Create**\nbutton.\n\n\n![create-ff-userlist](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/create-ff-userlist.png){:\n.shadow.medium.center.}\n\nCreating user list named \"prods-in-alphabetical-order-userlist”\n\n{: .note.text-center}\n\n\n- On the next screen, click on the **Add Users** button on the top right\nhand side of your screen.\n\n- In the **User IDs** text field, enter the following two email addresses\nand then click on the **Add** button:\n\n\n> michael@cfl.rr.com,mary@cfl.rr.com\n\n\n![add-users-to-list](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/add-users-to-list.png){:\n.shadow.medium.center}\n\nAdding users to user list \"prods-in-alphabetical-order-userlist”\n\n{: .note.text-center}\n\n\n- Head back to the Feature flags window by selecting **Deploy > Feature\nflags** from your left vertical navigation menu.\n\n\n### Creating the flag\n\n- Click on the **New feature flag** button on the top right hand side of\nyour screen.\n\n- In the **New feature flag** window, enter\n“prods-in-alphabetical-order-ff”.\n\n\n### Specifying the strategy for the production environment\n\nIn the **Strategies** section of the **New feature flag** window, there\nshould already be sub-sections for **Type** and **Environments**.\n\n- For **Type**, select **Percent rollout** from the dropdown menu.\n\n- For **Percentage**, enter **50** in the field.\n\n- For **Based on**, ensure that **Available ID** is selected from the\npopdown menu.\n\n- For **Environments**, click on the **+** sign and select the\n**production** environment.\n\n\n### Specifying the strategy for the staging environment\n\n- Click on the **Add strategy** button on the right hand side of the\n**Strategies** section. A new sub-section for another strategy will appear.\n\n- For **Type**, select **User List** from the dropdown menu.\n\n- For **User List**, select the user list\n**prods-in-alphabetical-order-userlist**.\n\n- For **Environments**, click on the **+** sign and select the **staging**\nenvironment.\n\n- Click on **Create feature flag** button at the bottom of your screen to\ncomplete the creation of the feature flag.\n\n\n![ff-and-strats-def](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/ff-and-strats-def.png){:\n.shadow.medium.center}\n\nDefining the feature flag with its strategies for strating and production\nenvironments\n\n{: .note.text-center}\n\n\n## Sharing feature flag configuration information with developers\n\nIn order for developers to instrument their code for this feature flag, you\nneed to share with them the following information:\n\n- On the **Feature flags** window, click on the **Configure** button on the\ntop right hand side of your screen.\n\n- Copy and save the values of **API URL** (URL where the client application\nconnects to get a list of feature flags) and **Instance ID** (unique token\nthat authorizes the retrieval of the feature flags). These are the two\nvalues that you will need for feature flag instrumentation.\n\n\n![ff-api-url-and-instance-id](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/ff-api-url-and-instance-id.png){:\n.shadow.medium.center}\n\nCopy and save the values for the feature flag API URL and Instance ID\n\n{: .note.text-center}\n\n\n- Head over to **Settings > CI/CD** and scroll down to the **Variables**\nsection and click on its **Expand** button. Add the following two variables\nto your project:\n\n\n| Variable Key | Variable Value | Variable Type | Environment Scope | Flag -\nProtect variable | Flag - Mask variable\n\n| ----------- | ----------- | ----------- |----------- | ----------- |\n----------- |\n\n| K8S_SECRET_UNLEASH_URL | \\\u003Csaved **API URL** value\\> | Variable | All\n(default) | unchecked | unchecked\n\n| K8S_SECRET_UNLEASH_INSTANCE_ID | \\\u003Csaved **Instance ID** value\\> |\nVariable | All (default) | unchecked | unchecked\n\n\n![add-var-K8S_SECRET_UNLEASH_URL](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/add-var-K8S_SECRET_UNLEASH_URL.png){:\n.shadow.medium.center}\n\nAdding variable K8S_SECRET_UNLEASH_URL to project \"prodmgr\"\n\n{: .note.text-center}\n\n\n![add-var-K8S_SECRET_UNLEASH_INSTANCE_ID](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/add-var-K8S_SECRET_UNLEASH_INSTANCE_ID.png){:\n.shadow.medium.center}\n\nAdding variable K8S_SECRET_UNLEASH_INSTANCE_ID to project \"prodmgr\"\n\n{: .note.text-center}\n\n\nThese two variables contain values that will be passed to your application\n(via the K8S_SECRET_ keyword) so that it can make use of the feature flags\ndefined and managed by GitLab.\n\n\nIn order for your application to be able to use feature flags, you need to\ninstrument your application with our Feature Flags framework. Let's see how\nyou do this in the sample Java application.\n\n\n## Instrumenting the code\n\nIn this example, we are using the Java client for Unleash but if you’re\nusing a different programming language then you need to use the client\nlibrary for your language. To get all the supported languages, refer to the\n[Unleash documentation](https://docs.getunleash.io/reference/sdks) or\n[Unleash open source\nproject](https://github.com/Unleash/unleash#unleash-sdks).\n\n\n### Instrumenting Java class files\n\n- In project “prodmgr”, navigate to the directory\n`src/main/java/csaa/jspring/ProductManager`.\n\n- Click on the file name “AppController.java” to view its contents and then\nclick on the Edit button to enter edit mode.\n\n- You will see a few code blocks that have been commented out and are\npreceded by the line:\n\n\n> // Uncomment block below to instrument Feature Flag\n\n\nUncomment all the code blocks under each of the lines indicated above.\n\n\n![java-file-with-uncommented-lines](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/java-file-with-uncommented-lines.png){:\n.shadow.medium.center}\n\nPartial view of AppController.java file with uncommented code blocks\n\n{: .note.text-center}\n\n\n- Commit the changes to the main branch.\n\n- The commit starts a pipeline that deploys the application to the staging\nenvironment. Head to **Build > Pipelines** and click on the most recently\nexecuted pipeline (should be the first one in the list). Click on the\npipeline to display it and wait until the **staging** job finishes. Then\ndeploy the application to production by clicking on “rollout 100%” job.\n\n\nNow that the application is running in the staging and production\nenvironments, let’s see the feature flag in action.\n\n\n## Feature flag in action\n\nNow let's check how the feature flag is working.\n\n### Checking the feature flag in the staging environment\n\n- In project “prodmgr”, click on **Operate > Environments** to see the list\nof all environments. Then click on the \"Open live environment\" button for\nthe staging environment.\n\n- A new browser tab will appear and will display a login screen. If your\nbrowser complains about the connection being insecure, accept the risk and\nopen the browser tab.\n\n- Remember that the feature flag strategy for staging is based on the user\nlist containing michael and mary in it. Let’s try logging in as each of\nthem.\n\n- Enter credentials michael@cfl.rr.com with password p33sw0rd. Verify that\nMichael gets a product list sorted in alphabetical order. Log out and close\nthe browser tab to ensure that his session closes.\n\n\n![michael-gets-ff](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/michael-gets-ff.png){:\n.shadow.medium.center}\n\nMichael gets the feature flag that orders the list of product names in\nalphabetical order\n\n{: .note.text-center}\n\n\n- From the Environments window, click on the \"Open live environment\" button\nfor the staging environment. Enter credentials \"mary@cfl.rr.com\" with\npassword \"p33sw0rd\". Verify that mary gets a product list sorted in\nalphabetical order. Log out and close the browser tab to ensure that her\nsession closes.\n\n- From the Environments window, click on the \"Open live environment\" button\nfor the staging environment. This time, enter credentials for\n\"thomas@gmail.com\" with password \"p33sw0rd\". Verify that thomas does **not**\nget a product list sorted in alphabetical order. Log out and close the\nbrowser tab to ensure that his session closes.\n\n\n![thomas-does-not-get-the-ff](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/thomas-does-not-get-the-ff.png){:\n.shadow.medium.center}\n\nThomas does not get the feature flag because the product names are not\nordered in alphabetical order\n\n{: .note.text-center}\n\n\nThe steps above demonstrate that the feature flag strategy for staging\nsuccessfully worked.\n\n\n### Checking the feature flag in the production environment\n\n- Click on **Operate > Environments** to see the list of all environments.\nThen click on the \"Open live environment\" button for the production\nenvironment.\n\n- A new browser tab will appear and will display a login screen. If your\nbrowser complains about the connection being insecure, accept the risk and\nopen the browser tab.\n\n- Remember that the strategy in production is that the feature will be\nserved to 50% of the users. Try logging into the web application as each of\nthe following users keeping track of who gets the list of products sorted in\nalphabetical order by name and who does not:\n\n\n**Note:** Remember to click on the \"Open live environment\" button for the\n**production** environment. Once you log out from each user, remember to\n**close** the browser tab to ensure that the session closes.\n\n\n| Username | Password\n\n| ----------- | ----------- |\n\n| peter@gmail.com | pa33w0rd\n\n| magic@cfl.rr.com | pa33w0rd\n\n| michael@cfl.rr.com | pa33w0rd\n\n| henry@gmail.com | pa33w0rd\n\n| mary@cfl.rr.com | pa33w0rd\n\n| thomas@gmail.com | pa33w0rd\n\n\nYour final count should consist of three users being served the feature and\nthree not, matching the strategy that was set for the production\nenvironment.\n\n\nAs changes are made to feature flags, you can track them from the audit\nevents window.\n\n\n## Auditing feature flag changes\n\n**Note:** A Premium GitLab subscription is needed for viewing Audit events.\n\n\n- In project “prodmgr”, select **Secure > Audit events** from the left\nvertical navigation menu.\n\n- This displays all the events that have occurred in GitLab for the last\nthirty days. You will see that events related to updates to feature flags\nare listed.\n\n\n![audit-events-list](https://about.gitlab.com/images/blogimages/feature-flags-tutorial/audit-events-list.png){:\n.shadow.medium.center}\n\nAudit events is an auditable list of actions that have been taken againt\nresources\n\n{: .note.text-center}\n\n\nThis auditing allows you to identify when and who made changes to feature\nflags. It can also help preempt out-of-compliance scenarios and streamline\naudits to avoid penalties, providing an opportunity to optimize cost, and\nlower risk of unscheduled production outages.\n\n\nNow you know how to create and use feature flags to lower your deployment\nrisk.\n\n\nPhoto by \u003Ca\nhref=\"https://unsplash.com/@liamdesic?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText\">Liam\nDesic\u003C/a> on \u003Ca\nhref=\"https://unsplash.com/photos/acKSt3THWKA?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText\">Unsplash\u003C/a>\n",[109,719,9],{"slug":1480,"featured":6,"template":698},"eliminate-risk-with-feature-flags-tutorial","content:en-us:blog:eliminate-risk-with-feature-flags-tutorial.yml","Eliminate Risk With Feature Flags Tutorial","en-us/blog/eliminate-risk-with-feature-flags-tutorial.yml","en-us/blog/eliminate-risk-with-feature-flags-tutorial",{"_path":1486,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1487,"content":1493,"config":1500,"_id":1502,"_type":14,"title":1503,"_source":16,"_file":1504,"_stem":1505,"_extension":19},"/en-us/blog/empowering-modelops-and-hpc-workloads-with-gpu-enabled-runners",{"title":1488,"description":1489,"ogTitle":1488,"ogDescription":1489,"noIndex":6,"ogImage":1490,"ogUrl":1491,"ogSiteName":686,"ogType":687,"canonicalUrls":1491,"schema":1492},"GPU-enabled runners for ModelOps and HPC workloads in CI/CD","Learn how to leverage our GitLab-hosted GPU-enabled runners for ModelOps and high-performance computing workloads.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749682702/Blog/Hero%20Images/gitlab-data-science-icon.png","https://about.gitlab.com/blog/empowering-modelops-and-hpc-workloads-with-gpu-enabled-runners","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Empower ModelOps and HPC workloads with GPU-enabled runners integrated with CI/CD\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Gabriel Engel\"}],\n        \"datePublished\": \"2023-07-06\",\n      }",{"title":1494,"description":1489,"authors":1495,"heroImage":1490,"date":1497,"body":1498,"category":781,"tags":1499},"Empower ModelOps and HPC workloads with GPU-enabled runners integrated with CI/CD",[1496],"Gabriel Engel","2023-07-06","\u003Ci>This blog post is the latest in an ongoing series about GitLab's journey\nto [build and integrate AI/ML into our DevSecOps\nplatform](/blog/ai-ml-in-devsecops-series/). Start with the first\nblog post: [What the ML is up with DevSecOps and\nAI?](/blog/what-the-ml-ai/). Throughout the series, we'll feature\nblogs from our product, engineering, and UX teams to showcase how we're\ninfusing AI/ML into GitLab.\u003C/i>\n\n\nIn today's fast-paced world, organizations are constantly looking to improve\ntheir [ModelOps](/direction/modelops/) and high-performance computing (HPC)\ncapabilities. Leveraging powerful graphical processing units\n([GPUs](https://www.techtarget.com/searchvirtualdesktop/definition/GPU-graphics-processing-unit))\nhas become a game-changer for accelerating machine learning workflows and\ncompute-intensive tasks. To help meet these evolving needs, we recently\nreleased our first GPU-enabled runners on GitLab.com.\n\n\nSecurely hosting a GitLab Runner environment for ModelOps and HPC is\nnon-trivial and requires a lot of knowledge and time to set up and maintain.\nIn this blog post, we'll look at some real-world examples of how you can\nharness the potential of GPU computing for ModelOps or HPC workloads while\ntaking full advantage of a SaaS solution.\n\n\n## What are GPU-enabled runners?\n\nGPU-enabled runners are dedicated computing resources for the AI-powered\nDevSecOps platform. They provide accelerated processing power for ModelOps\nand HPC such as the training or deployment of large language models\n([LLMs](https://www.techtarget.com/whatis/definition/large-language-model-LLM))\nas part of ModelOps workloads. In the first iteration of releasing\nGPU-enabled runners, [GitLab.com SaaS\noffers](https://docs.gitlab.com/ee/ci/runners/saas/gpu_saas_runner.html) the\nGCP `n1-standard-4` machine type (4 vCPU, 15 GB memory) with 1 NVIDIA T4 (16\nGB memory) attached. The runner behaves like a GitLab Runner on Linux, using\nthe docker+machine [executor](https://docs.gitlab.com/runner/executors/). \n\n\n## Using GPU-enabled runners\n\nTo take advantage of GitLab GPU-enabled runners, follow these steps:\n\n\n### 1. Have a project on GitLab.com\n\nAll projects on GitLab.com SaaS with a `Premium` or `Ultimate`\n[subscription](https://about.gitlab.com/pricing/) have the GPU-enabled\nrunners enabled by default - no additional configuration is required.\n\n\n### 2. Create a job running on GPU-enabled runners\n\nCreate a job in your `.gitlab-ci.yml` configuration file, and set the\n[runner\n`tag`](https://docs.gitlab.com/ee/ci/runners/configure_runners.html#use-tags-to-control-which-jobs-a-runner-can-run)\nto the `saas-linux-medium-amd64-gpu-standard` value. \n\n\n```yaml\n\ngpu-job:\n  stage: build\n  tags:\n    - saas-linux-medium-amd64-gpu-standard\n```\n\n\n### 3. Select a Docker image with the Nvidia CUDA driver\n\n\nThe CI/CD job runs in an isolated virtual machine (VM) with a\nbring-your-own-image policy as with [GitLab SaaS runners on\nLinux](https://docs.gitlab.com/ee/ci/runners/saas/linux_saas_runner.html).\nGitLab mounts the GPU from the host VM into your isolated environment. You\nmust use a Docker image with the GPU driver installed to use the GPU. For\nNvidia GPUs, you can use the [CUDA\nToolkit](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/cuda)\ndirectly, or third-party images with Nvidia drivers installed, such as the\n[TensorFlow GPU image](https://hub.docker.com/r/tensorflow/tensorflow/).\n\n\nThe CI/CD job configuration for the Nvidia CUDA base Ubuntu image looks like\nthis:\n\n\n```yaml\n  image: nvcr.io/nvidia/cuda:12.1.1-base-ubuntu22.04\n```\n\n\n### 4. Verify that the GPU is working\n\nTo verify that the GPU drivers are working correctly, you can execute the\n`nvidia-smi` command in the CI/CD job `script` section. \n\n\n```yaml\n  script:\n    - nvidia-smi\n```\n\n\n## Basic usage examples\n\nLet's explore some basic scenarios where GPU-enabled runners can supercharge\nyour ModelOps and HPC workloads:\n\n\n### Example 1: ModelOps with Python\n\nIn this example, we train a model on our GPU-enabled runner defined in the\n`train.py` file using the Nvidia CUDA base Ubuntu image mentioned earlier.\n\n\n`.gitlab-ci.yml` file:\n\n```yaml\n\nmodel-training:\n  stage: build\n  tags:\n    - saas-linux-medium-amd64-gpu-standard\n  image: nvcr.io/nvidia/cuda:12.1.1-base-ubuntu22.04\n  script:\n    - apt update\n    - apt install -y --no-install-recommends python3 python3-pip \n    - pip3 install -r requirements.txt\n    - python3 --version\n    - python3 train.py\n```\n\n\n### Example 2: Scientific simulations and HPC\n\nComplex scientific simulations require significant computing resources.\nGPU-enabled runners can accelerate these simulations, allowing you to get\nresults in less time.\n\n\n`.gitlab-ci.yml` file:\n\n```yaml\n\nsimulation-run:\n  stage: build\n  tags:\n    - saas-linux-medium-amd64-gpu-standard\n  image: nvcr.io/nvidia/cuda:12.1.1-base-ubuntu22.04\n  script:\n    - ./run_simulation --input input_file.txt\n```\n\n\n## Advanced usage examples\n\nLet's go through some real-world scenarios of how we use GPU-enabled runners\nat GitLab.\n\n\n### Example 3: Python model training with a custom Docker image\n\nFor our third example, we will use this [handwritten digit recognition\nmodel](https://gitlab.com/gitlab-org/modelops/demos/handwritten-digit-recognition).\nWe are using this project as a demo to showcase or try out new ModelOps\nfeatures.\n\n\n[Open the\nproject](https://gitlab.com/gitlab-org/modelops/demos/handwritten-digit-recognition)\nand fork it into your preferred namespace. You can follow the next steps\nusing the [Web IDE](https://docs.gitlab.com/ee/user/project/web_ide/) in the\nbrowser, or clone the project locally to create and edit the files. Some of\nthe next steps require you to override existing configuration in the\n`Dockerfile` and `.gitlab-ci.yml`. \n\n\nAs we need more pre-installed components and want to save installation time\nwhen training the model, we decided to create a custom Docker image with all\ndependencies pre-installed. This also gives us full control over the build\nenvironment we use and allows us to reuse it locally without relying on the\n`.gitlab-ci.yml' implementation.\n\n\nIn addition, we are using a more complete pipeline configuration with the\nfollowing stages:\n\n\n```yaml\n\nstages:\n  - build\n  - test\n  - train\n  - publish\n```\n\n\n![GPU pipeline\noverview](https://about.gitlab.com/images/blogimages/2023-07-06-gpu-enabled-runners-for-modelops/pipeline-overview.png)\n\n\n#### Building a custom Docker image\n\nThe first step is to define a `Dockerfile`. In this example, we start with\nthe Nvidia CUDA base Ubuntu image and then install `Python3.10`. Using `pip\ninstall`, we then add all the required libraries specified in a\n`requirements.txt` file.\n\n\n```docker\n\nFROM nvcr.io/nvidia/cuda:12.1.1-base-ubuntu22.04\n\n\n1. Update and install required packages\n\nRUN apt-get update && apt-get install -y \\\n    python3.10 \\\n    python3.10-dev \\\n    python3-pip \\\n    && rm -rf /var/lib/apt/lists/*\n\n2. Set Python 3.10 as the default Python version\n\nRUN ln -s /usr/bin/python3.10 /usr/bin/python\n\n\n3. Copy the requirements.txt file\n\nCOPY requirements.txt /tmp/requirements.txt\n\n\n4. Install Python dependencies\n\nRUN pip3 install --no-cache-dir -r /tmp/requirements.txt\n\n```\n\n\nIn the `.gitlab-ci.yml` file we use\n[Kaniko](https://docs.gitlab.com/ee/ci/docker/using_kaniko.html) to build\nthe Docker image and push it into the [GitLab Container\nRegistry](https://docs.gitlab.com/ee/user/packages/container_registry/).\n\n\n```yaml\n\nvariables:\n  IMAGE_PATH: \"${CI_REGISTRY_IMAGE}:latest\"\n  GIT_STRATEGY: fetch\n\ndocker-build:\n  stage: build\n  tags:\n    - saas-linux-medium-amd64\n  image:\n    name: gcr.io/kaniko-project/executor:v1.9.0-debug\n    entrypoint: [\"\"]\n  script:\n    - /kaniko/executor\n      --context \"${CI_PROJECT_DIR}\"\n      --dockerfile \"${CI_PROJECT_DIR}/Dockerfile\"\n      --destination \"${IMAGE_PATH}\"\n      --destination \"${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}\"\n  rules:\n    - if: $CI_COMMIT_TAG\n```\n\n\nIn [rules](https://docs.gitlab.com/ee/ci/yaml/#rules) we define to only\ntrigger the Docker image build for a new git tag. The reason is simple - we\ndon't want to run the image build process for every time we train the model.\n\n\nTo start the image build job [create a new Git\ntag](https://docs.gitlab.com/ee/user/project/repository/tags/#create-a-tag).\nYou can either do this by using `git tag -a v0.0.1` command or via UI.\nNavigate into `Code > Tags` and click on `New Tag`. As Tag name type\n`v0.0.1` to create a new Git tag and trigger the job.\n\n\nNavigate to `Build > Pipelines` to verify the `docker-build` job status, and\nthen locate the tagged image following [`Deploy > Container\nRegistry`](https://docs.gitlab.com/ee/user/packages/container_registry/).\n\n\n![Docker\nimage](https://about.gitlab.com/images/blogimages/2023-07-06-gpu-enabled-runners-for-modelops/gpu-docker-image.png)\n\n\n#### Testing the Docker image\n\nTo test the image, we will use the following `test-image` job and run\n`nvidia-smi` and check that the GPU drivers are working correctly.\n\n\nThe job configuration in `.gitlab-ci.yml` file looks as follows:\n\n\n```yaml\n\ntest-image:\n  stage: test\n  tags:\n    - saas-linux-medium-amd64-gpu-standard\n  image: $IMAGE_PATH\n  script:\n    - nvidia-smi\n  rules:\n    - if: $CI_COMMIT_TAG\n```\n\n\nWe also include container scanning and more [security\nscanning](https://docs.gitlab.com/ee/user/application_security/) templates\nin the `.gitlab-ci.yml` file.\n\n\n```yaml\n\ninclude:\n  - template: Security/Secret-Detection.gitlab-ci.yml\n  - template: Security/Container-Scanning.gitlab-ci.yml\n  - template: Jobs/Dependency-Scanning.gitlab-ci.yml\n  - template: Security/SAST.gitlab-ci.yml\n```\n\n\n#### Training the model with our custom Docker image\n\nNow that we have built our Custom docker image, we can train the model\nwithout installing any more dependencies in the job.\n\n\nThe train job in our `.gitlab-ci.yml` looks like this:\n\n\n```yaml\n\ntrain:\n  stage: train\n  tags:\n    - saas-linux-medium-amd64-gpu-standard\n  image: $IMAGE_PATH\n  script:\n    - python train_digit_recognizer.py\n  artifacts:\n    paths:\n      - mnist.h5\n    expose_as: 'trained model'\n```\n\n\nNavigate to `Build > Pipelines` to see the job logs.\n\n\n![Train job\nlogs](https://about.gitlab.com/images/blogimages/2023-07-06-gpu-enabled-runners-for-modelops/train-job-log.png)\n\n\nFrom here, you can also inspect the `train` job artifacts.\n\n\n#### Publishing the model\n\nIn the last step of our `.gitlab-ci.yml` file, we are going to publish the\ntrained model.\n\n\n```yaml\n\npublish:\n  stage: publish\n  when: manual\n  dependencies:\n    - train\n  image: curlimages/curl:latest\n  script:\n    - 'curl --header \"JOB-TOKEN: $CI_JOB_TOKEN\" --upload-file mnist.h5 \"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/MNIST-Model/${CI_COMMIT_TAG}/mnist.h5\"'\n```\n\n\nNavigate to `Build > Pipelines` and trigger the `publish` job manually.\nAfter that, navigate into `Deploy > Package Registry` to verify the uploaded\ntrained model.\n\n\n![Package\nRegistry](https://about.gitlab.com/images/blogimages/2023-07-06-gpu-enabled-runners-for-modelops/package-registry.png)\n\n\n### Example 4: Jupyter notebook model training for ML-powered GitLab Issue\ntriage\n\n\nIn the last example, we are using our GPU-enabled runner to train the\ninternal [GitLab model to triage\nissues](https://gitlab.com/gitlab-org/ml-ops/tanuki-stan/-/tree/using-gpu-enabled-runner).\nWe use this model at GitLab to determine and assign issues to the right team\nfrom the context of the issue description.\n\n\nDifferent from the previous examples, we now use the [`tensorflow-gpu`\ncontainer image](https://hub.docker.com/r/tensorflow/tensorflow) and install\nthe\n[requirements](https://gitlab.com/gitlab-org/ml-ops/tanuki-stan/-/blob/using-gpu-enabled-runner/notebooks/requirements.tensorflow-gpu.txt)\nin the job itself.\n\n\n`.gitlab-ci.yml` configuration:\n\n\n```yaml\n\ntrain:\n  tags:\n    - saas-linux-medium-amd64-gpu-standard\n  image: tensorflow/tensorflow:2.4.1-gpu\n  script:\n    - nvidia-smi\n    - cd notebooks\n    - pip install -r requirements.tensorflow-gpu.txt\n    - jupyter nbconvert --to script classify_groups.ipynb\n    - apt-get install -y p7zip-full\n    - cd ../data\n    - 7z x -p${DATA_PASSWORD} gitlab-issues.7z\n    - cd ../notebooks\n    - python3 classify_groups.py\n  artifacts:\n    paths:\n      - models/\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH  \n      when: manual\n      allow_failure: true\n```\n\n\n![TensorFlow\ntrain](https://about.gitlab.com/images/blogimages/2023-07-06-gpu-enabled-runners-for-modelops/tensorflow-train.png)\n\n\nIf you are interested in another Jupyter notebook example, check out our\nrecently published video on [Training ML Models using GPU-enabled\nrunner](https://youtu.be/tElegG4NCZ0).\n\n\n\u003Ciframe width=\"768\" height=\"432\"\nsrc=\"https://www.youtube.com/embed/tElegG4NCZ0\" title=\"YouTube video player\"\nframeborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write;\nencrypted-media; gyroscope; picture-in-picture; web-share\"\nallowfullscreen>\u003C/iframe>\n\n\n## Results\n\nThe integration of GPU-enabled runners on GitLab.com SaaS opens up a new\nrealm of possibilities for ModelOps and HPC workloads.\n\nBy harnessing the power of GPU-enabled runners, you can accelerate your\nmachine learning workflows, enable faster data processing, and improve\nscientific simulations, all while taking full advantage of a SaaS solution\nand avoiding the hurdles of hosting and maintaining your own build hardware.\n\n\nWhen you try the GPU-enabled runners, please share your experience in our\n[feedback issue](https://gitlab.com/gitlab-org/gitlab/-/issues/403008).\n\n\nCompute-heavy workloads can take a long time. A known problem is timeouts\nafter three hours because of the current [configuration of GitLab SaaS\nrunners](https://docs.gitlab.com/ee/ci/runners/#how-saas-runners-work).\n\nWe plan to release more powerful compute for future iterations to handle\nheavier workloads faster. You can follow updates about GPU-enabled runners\nin the [GPU-enabled runners\nepic](https://gitlab.com/groups/gitlab-org/-/epics/8648) and learn more in\nthe [GPU-enabled runners\ndocumentation](https://docs.gitlab.com/ee/ci/runners/saas/gpu_saas_runner.html).\n",[9,717,109,848,719],{"slug":1501,"featured":6,"template":698},"empowering-modelops-and-hpc-workloads-with-gpu-enabled-runners","content:en-us:blog:empowering-modelops-and-hpc-workloads-with-gpu-enabled-runners.yml","Empowering Modelops And Hpc Workloads With Gpu Enabled Runners","en-us/blog/empowering-modelops-and-hpc-workloads-with-gpu-enabled-runners.yml","en-us/blog/empowering-modelops-and-hpc-workloads-with-gpu-enabled-runners",{"_path":1507,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1508,"content":1511,"config":1517,"_id":1519,"_type":14,"title":1520,"_source":16,"_file":1521,"_stem":1522,"_extension":19},"/en-us/blog/enhance-application-quality-with-ai-powered-test-generation",{"noIndex":6,"title":1509,"description":1510},"Enhance application quality with AI-powered test generation","Learn how GitLab Duo with Amazon Q improves the QA process by automatically generating comprehensive unit tests.",{"title":1509,"description":1510,"authors":1512,"heroImage":1513,"date":1514,"body":1515,"category":781,"tags":1516},[1475],"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659604/Blog/Hero%20Images/Screenshot_2024-11-27_at_4.55.28_PM.png","2025-07-03","You know how critical application quality is to your customers and reputation. However, ensuring that quality through comprehensive testing can feel like an uphill battle. You're dealing with time-consuming manual processes, inconsistent test coverage across your team, and those pesky issues that somehow slip through the cracks. It's frustrating when your rating drops because quality assurance becomes a bottleneck rather than a safeguard.\n\nHere's where [GitLab Duo with Amazon Q ](https://about.gitlab.com/blog/gitlab-duo-with-amazon-q-agentic-ai-optimized-for-aws/), which delivers agentic AI throughout the software development lifecycle for AWS customers, can help transform your QA process. This AI-powered capability can automatically generate comprehensive unit tests for your code, dramatically accelerating your quality assurance workflow. Instead of spending hours writing tests manually, you can let AI analyze your code and create tests that ensure optimal coverage and consistent quality across your entire application.\n\n## How GitLab Duo with Amazon Q works\n\nSo how does this work? Let's walk through the process together.\nWhen you're working on a new feature, you start by selecting the Java class you've added to your project through a merge request. You simply navigate to your merge request and click on the \"Changes\" tab to see the new code you've added.\n\nNext, you invoke Amazon Q by entering a quick action command. All you need to do is type `/q test` in the issue comment box. It's that simple – just a forward slash, the letter \"q\", and the word \"test\".\n\nOnce you hit enter, Amazon Q springs into action. It analyzes your selected code, understanding its structure, logic, and purpose. The AI examines your class methods, dependencies, and potential edge cases to determine what tests are needed.\n\nWithin moments, Amazon Q generates comprehensive unit test coverage for your new class. It creates tests that cover not just the happy path, but also edge cases and error conditions you might have overlooked. The generated tests follow your project's existing patterns and conventions, ensuring they integrate seamlessly with your codebase.\n\n## Why use GitLab Duo with Amazon Q?\n\nHere's the bottom line: You started with a critical challenge – maintaining high-quality applications while dealing with time constraints and inconsistent testing practices. GitLab Duo with Amazon Q addresses this by automating the test generation process, ensuring optimal code coverage and consistent testing standards. The result? Issues are detected before deployment, your applications maintain their quality, and you can develop software faster without sacrificing reliability.\n\nKey benefits of this feature:\n\n* Significantly reduces time spent writing unit tests\n* Ensures comprehensive test coverage across your codebase\n* Maintains consistent testing quality across all team members\n* Catches issues before they reach production\n* Accelerates your overall development velocity\n\nReady to see this game-changing feature in action? Watch how GitLab Duo with Amazon Q can transform your quality assurance process:\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/pxlYJVcHY28?si=MhIz6lnHxc6kFhlL\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Get started with GitLab Duo with Amazon Q today\n\nWant to learn more about GitLab Duo with Amazon Q? Visit the [GitLab and AWS partner page](https://about.gitlab.com/partners/technology-partners/aws/) for detailed information.\n\n## Agentic AI resources\n- [Agentic AI guides and resources](https://about.gitlab.com/blog/agentic-ai-guides-and-resources/)\n- [What is agentic AI?](https://about.gitlab.com/topics/agentic-ai/)\n- [GitLab Duo with Amazon Q: Agentic AI optimized for AWS generally available](https://about.gitlab.com/blog/gitlab-duo-with-amazon-q-agentic-ai-optimized-for-aws/)\n- [GitLab Duo with Amazon Q documentation](https://docs.gitlab.com/user/duo_amazon_q/)",[717,848,1198,9,827,1084],{"featured":91,"template":698,"slug":1518},"enhance-application-quality-with-ai-powered-test-generation","content:en-us:blog:enhance-application-quality-with-ai-powered-test-generation.yml","Enhance Application Quality With Ai Powered Test Generation","en-us/blog/enhance-application-quality-with-ai-powered-test-generation.yml","en-us/blog/enhance-application-quality-with-ai-powered-test-generation",{"_path":1524,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1525,"content":1531,"config":1538,"_id":1540,"_type":14,"title":1541,"_source":16,"_file":1542,"_stem":1543,"_extension":19},"/en-us/blog/enhance-application-security-with-gitlab-hackerone",{"title":1526,"description":1527,"ogTitle":1526,"ogDescription":1527,"noIndex":6,"ogImage":1528,"ogUrl":1529,"ogSiteName":686,"ogType":687,"canonicalUrls":1529,"schema":1530},"Enhance application security with GitLab + HackerOne","Learn about the GitLab + HackerOne partnership and how to easily implement an integration that improves your organization’s application security posture.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097503/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%2810%29_5ET24Q6i8ihqrAOkge7a1R_1750097503214.png","https://about.gitlab.com/blog/enhance-application-security-with-gitlab-hackerone","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Enhance application security with GitLab + HackerOne\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Fernando Diaz\"}],\n        \"datePublished\": \"2025-04-03\",\n      }",{"title":1526,"description":1527,"authors":1532,"heroImage":1528,"date":1534,"body":1535,"category":694,"tags":1536},[1533],"Fernando Diaz","2025-04-03","Security can no longer be an afterthought in the development process.\nOrganizations need robust solutions that integrate security throughout the\nentire software development lifecycle. This is where the partnership between\nHackerOne and GitLab creates a compelling combination for modern application\ndevelopment teams.\n\n\nGitLab, the comprehensive, AI-powered DevSecOps platform, and HackerOne, the\nleading crowd-sourced security platform, have established a partnership that\nbrings together the best of both worlds: GitLab's streamlined DevSecOps\nworkflow and HackerOne's powerful vulnerability management capabilities.\n\n\nIn this tutorial, you'll learn how to enhance developer productivity and\nyour security posture by implementing HackerOne's GitLab integration.\n\n\n## An integration that empowers developers\n\n\nHackerOne's GitLab integration is remarkably straightforward, yet powerful.\nWhen security researchers discover vulnerabilities through HackerOne's\nplatform, these findings are automatically converted into GitLab issues.\nThis creates a seamless workflow where:\n\n\n* Security researchers identify vulnerabilities via HackerOne's platform  \n\n* Validated vulnerabilities are automatically converted into GitLab issues  \n\n* Development teams can address these issues directly within their existing\nworkflow  \n\n* Resolution status is synchronized between both platforms\n\n\nYou can start leveraging the benefits of GitLab and HackerOne by using the\n[integration](https://docs.hackerone.com/en/articles/8571227-gitlab-integration)\nto track GitLab issues as references on HackerOne. This integration provides\nbi-directional and seamless data syncing between your HackerOne report and\nGitLab issues, improving alignment between development and security teams\nwhile streamlining security vulnerability processing.\n\n\nTo configure the GitLab integration to sync information between your\nHackerOne report and your Gitlab issue, follow the instructions provided in\n[HackerOne's GitLab integration\ndocumentation](https://docs.hackerone.com/en/articles/10394699-gitlab-setup),\nwhich includes:\n\n\n1. [Setting up an OAuth 2.0\napplication](https://docs.gitlab.com/ee/integration/oauth_provider.html) for\nyour GitLab instance with the provided HackerOne settings  \n\n2. Connecting HackerOne to the newly created OAuth 2.0 on GitLab  \n\n3. Authorizing HackerOne to access the GitLab API  \n\n4. Configuring which GitLab project you would like to escalate HackerOne\nreports to  \n\n5. Selecting the HackerOne fields to map to corresponding GitLab fields  \n\n6. GitLab-to-HackerOne and HackerOne-to-GitLab event configuration\n\n\nOnce the integration is in place, you’ll be able to seamlessly sync data\nbi-directionally between both GitLab and HackerOne. This helps simplify\ncontext-switching and allows vulnerabilities to be tracked with ease\nthroughout both systems. The integration allows for the following features:\n\n\n* **Creating a GitLab Issue from HackerOne:** You can create new GitLab\nissues for reports you receive on HackerOne.  \n\n* **Linking HackerOne reports to existing GitLab tasks.**   \n\n* **Syncing updates from HackerOne to GitLab:** The following updates on a\nreport are synced as a comment to GitLab.  \n  * Report comments  \n  * State changes  \n  * Rewards  \n  * Assignee changes  \n  * Public disclosure  \n  * Close GitLab Issue  \n* **Syncing Updates from GitLab to HackerOne:** The following updates on\nGitLab will be reflected in HackerOne as an internal comment on the\nassociated report:  \n  * Comments  \n  * State changes  \n* **HackerOne severity to GitLab label mapping**: Allows you to set a custom\npriority when escalating a report to GitLab.  \n\n* **Due date mapping:** Allows you to automatically set a custom due date\nbased on the severity of a report.\n\n\n![GitLab + HackerOne adding comments or change the state of the report in\nGitLab](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097510/Blog/Content%20Images/Blog/Content%20Images/sync_aHR0cHM6_1750097509644.png)\n\n\nThese features improve alignment between development and security teams and\nstreamlining security vulnerability processing. To learn more on how the\nintegration works, see the [integration\ndocumentation](https://docs.hackerone.com/en/articles/8571227-gitlab-integration).\n\n\n## A look into HackerOne bug bounty programs\n\n\nHackerOne provides bug bounty programs or cybersecurity initiatives where\nrewards are offered for discovering and reporting vulnerabilities in\ncustomers’ software systems, websites, or applications. Bug bounty programs\nhelp enhance the security of an application by:\n\n\n* Identifying security flaws before malicious actors can exploit them  \n\n* Leveraging diverse expertise from a global community of security\nresearchers  \n\n* Providing a cost-effective way to improve cybersecurity  \n\n* Complementing internal security efforts and traditional penetration\ntesting\n\n\nGitLab utilizes HackerOne’s bug bounty program, allowing security\nresearchers to report vulnerabilities in GitLab applications or\ninfrastructure. This crowdsourced approach helps GitLab identify and address\npotential security issues more effectively.\n\n\n![HackerOne GitLab Bug Bounty\npage](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097510/Blog/Content%20Images/Blog/Content%20Images/hackerone_gitlab_bug_bounty_page_aHR0cHM6_1750097509645.png)\n\n\nBy leveraging HackerOne's platform and the global hacker community,\norganizations can significantly enhance their security posture, identify\nvulnerabilities faster, and stay ahead of potential threats.\n\n\n## Secure applications and improve efficiency with GitLab \n\n\nGitLab provides a complete DevSecOps platform, which enables functionality\nfor the complete software development lifecycle, including security and\ncompliance tools. GitLab supports the following security scanner types:\n\n- Static Application Security Testing (SAST)\n\n- Dynamic Application Security Testing (DAST)\n\n- Container Scanning\n\n- Dependency Scanning\n\n- Infrastructure as Code Scanning\n\n- Coverage-guided Fuzzing\n\n- Web API Fuzzing\n\n\nWith GitLab, you can add security scanning by simply applying a template to\nyour CI/CD pipeline definition file. For example, enabling SAST just takes a\nfew lines of code in the `.gitlab-ci.yml`:\n\n\n```yaml\n\nstage:\n  - test\n\ninclude:\n  - template: Jobs/SAST.gitlab-ci.yml\n```\n\n\nThis will run SAST on the test stage, and [auto-detect the languages\nused](https://docs.gitlab.com/ee/user/application_security/sast/#supported-languages-and-frameworks)\nin your application. Then, whenever you create a merge request, SAST will\ndetect the vulnerabilities in the diff between the feature branch and the\ntarget branch and provide relevant data on each vulnerability to assist with\nremediation.\n\n\n![NoSQL injection vulnerability seen in\nMR](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097510/Blog/Content%20Images/Blog/Content%20Images/no_sql_injection_vulnerability_mr_view_aHR0cHM6_1750097509647.png)\n\n\nThe results of the SAST scanner can block code from being merged if security\npolicies are applied. Native GitLab users can be set as approvers, allowing\nrequired reviews before merging insecure code. This assures that all\nvulnerabilities have oversight from the appropriate parties.\n\n\n![Merge request approval\npolicy](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097510/Blog/Content%20Images/Blog/Content%20Images/merge_request_approval_policy_aHR0cHM6_1750097509649.png)\n\n\nHackerOne has integrated GitLab into its operations and development\nprocesses in several significant ways, which have led to development process\nimprovements and enhanced scalability and collaboration. These improvements\ninclude faster deployments and cross-team planning.\n\n\n## Key benefits of HackerOne's GitLab integration\n\n\nThe key benefits of using HackerOne and GitLab together include:\n\n\n* **Enhanced security visibility:** Development teams gain immediate\nvisibility into security vulnerabilities without leaving their primary\nworkflow environment. This real-time awareness helps teams prioritize\nsecurity issues alongside feature development.  \n\n* **Streamlined remediation process:** By converting HackerOne reports\ndirectly into GitLab issues, the remediation process becomes part of the\nstandard development cycle. This eliminates context switching between\nplatforms and ensures security fixes are tracked alongside other development\nwork.  \n\n* **Accelerated time to fix:** The integration significantly reduces the\ntime between vulnerability discovery and resolution. With HackerOne\nsubmissions immediately available in GitLab, development teams can begin\nworking on fixes without delay, improving overall security posture.  \n\n* **Improved collaboration:** Security researchers, security teams, and\ndevelopers can communicate more effectively through this integration.\nComments and updates flow between both platforms, creating a collaborative\nenvironment focused on improving security.  \n\n* **Real-world impact:** Organizations implementing the HackerOne and GitLab\nintegration have reported:  \n  * Up to 70% reduction in time from vulnerability discovery to fix  \n  * Improved developer satisfaction by keeping them in their preferred workflow  \n  * Enhanced security visibility across the organization  \n  * More effective allocation of security resources\n\n> To get started today, visit [the integration setup\npage](https://docs.hackerone.com/en/articles/10394699-gitlab-setup) today.\n\n\n## Learn more\n\n\nTo learn more about GitLab and HackerOne, and how we can help enhance your\nsecurity posture, check out the following resources:\n\n* [HackerOne's GitLab Integration\nUsage](https://docs.hackerone.com/en/articles/8571227-gitlab-integration)  \n\n* [HackerOne GitLab Bug Bounty\nProgram](https://hackerone.com/gitlab?type=team)\n\n* [GitLab Security and Compliance\nSolutions](https://about.gitlab.com/solutions/security-compliance/)  \n\n* [HackerOne achieves 5x faster deployments with GitLab’s integrated\nsecurity](https://about.gitlab.com/customers/hackerone/)  \n\n* [GitLab Application Security\nDocumentation](https://docs.gitlab.com/ee/user/application_security/)\n",[694,827,233,284,496,9,1537],"bug bounty",{"slug":1539,"featured":6,"template":698},"enhance-application-security-with-gitlab-hackerone","content:en-us:blog:enhance-application-security-with-gitlab-hackerone.yml","Enhance Application Security With Gitlab Hackerone","en-us/blog/enhance-application-security-with-gitlab-hackerone.yml","en-us/blog/enhance-application-security-with-gitlab-hackerone",{"_path":1545,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1546,"content":1552,"config":1558,"_id":1560,"_type":14,"title":1561,"_source":16,"_file":1562,"_stem":1563,"_extension":19},"/en-us/blog/expanding-gitlab-for-startups-program",{"title":1547,"description":1548,"ogTitle":1547,"ogDescription":1548,"noIndex":6,"ogImage":1549,"ogUrl":1550,"ogSiteName":686,"ogType":687,"canonicalUrls":1550,"schema":1551},"Expanding GitLab for Startups program","Learn how startups can access the complete DevSecOps platform.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664087/Blog/Hero%20Images/tanukicover.jpg","https://about.gitlab.com/blog/expanding-gitlab-for-startups-program","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Expanding GitLab for Startups program\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Emilio Salvador\"}],\n        \"datePublished\": \"2023-03-01\",\n      }",{"title":1547,"description":1548,"authors":1553,"heroImage":1549,"date":1554,"body":1555,"category":994,"tags":1556},[991],"2023-03-01","\nGitLab is committed to supporting the startup community, and we are excited to announce the expansion of our [GitLab for Startups program](/solutions/startups/). Our goal has always been to help businesses of all sizes streamline their development processes and improve collaboration, and we recognize the unique challenges that startups face. \n\nStarting on March 15, 2023, our GitLab for Startups program will include qualifying startups backed by external funding. Based on funding level and years in the program, qualifying startups are able to utilize our complete DevSecOps platform at a highly discounted price or possibly at no cost for the first year. The program will continue supporting eligible startups with deep discounts in the second year.  \n\nWith GitLab, startups are able to reduce software development cycles, reduce time to market, and improve product quality. By adopting a single application for the entire DevSecOps lifecycle, startups can develop software faster and focus more on growing their customer base, increasing revenue, and differentiating their product in the market.\n\n![Chart listing eligibility requirements](https://about.gitlab.com/images/blogimages/gitlabforstartupscriteria.png)\n\nQualifying startups can submit the application form on our [GitLab for Startups page](/solutions/startups/join/) starting on March 15, 2023. For additional questions regarding this offer, please see our FAQ section on the GitLab for Startups page or feel free to reach out to us at startups@gitlab.com.\n",[9,1557,994],"startups",{"slug":1559,"featured":6,"template":698},"expanding-gitlab-for-startups-program","content:en-us:blog:expanding-gitlab-for-startups-program.yml","Expanding Gitlab For Startups Program","en-us/blog/expanding-gitlab-for-startups-program.yml","en-us/blog/expanding-gitlab-for-startups-program",{"_path":1565,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1566,"content":1571,"config":1577,"_id":1579,"_type":14,"title":1580,"_source":16,"_file":1581,"_stem":1582,"_extension":19},"/en-us/blog/explain-this-vulnerability",{"title":1567,"description":1568,"ogTitle":1567,"ogDescription":1568,"noIndex":6,"ogImage":1549,"ogUrl":1569,"ogSiteName":686,"ogType":687,"canonicalUrls":1569,"schema":1570},"ML experiment: Explain this vulnerability","Learn how GitLab is experimenting with vulnerability explanation and mitigation recommendations in this latest installment of our ongoing 'AI/ML in DevSecOps' series.","https://about.gitlab.com/blog/explain-this-vulnerability","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"ML experiment: Explain this vulnerability\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Alana Bellucci\"}],\n        \"datePublished\": \"2023-05-02\",\n      }",{"title":1567,"description":1568,"authors":1572,"heroImage":1549,"date":1574,"body":1575,"category":781,"tags":1576},[1573],"Alana Bellucci","2023-05-02","\n\n\u003Ci>This blog is the latest post an ongoing series about GitLab’s journey to [build and integrate AI/ML into our DevSecOps platform](/blog/ai-ml-in-devsecops-series/). The first blog post can be found [here](/blog/what-the-ml-ai/). Throughout the series, we’ll feature blogs from our product, engineering, and UX teams to showcase how we’re infusing AI/ML into GitLab.\u003C/i>\n\nGitLab surfaces vulnerabilities that contain relevant information. However, more often users aren't sure where to start. \nIt takes time to research and synthesize information that is surfaced within the vulnerability record. Moreover, figuring out how to fix a given vulnerability can be difficult.\n\nTo help teams identify an effective way to fix a vulnerability within the context of their specific code base, we have released an [experimental](https://docs.gitlab.com/ee/policy/experiment-beta-support.html#experiment)\n feature that provides GitLab AI-assisted vulnerability recommendations leveraging the explanatory power of large language models. This capability combines basic vulnerability \n information with insights derived from the customer's code to explain the vulnerability in context, demonstrate how it can be exploited, and provide an example fix.\n\n[Isaac Dawson](https://gitlab.com/idawson) and [Dinesh Bolkensteyn](https://gitlab.com/dbolkensteyn), both [GitLab Vulnerability Research](/handbook/engineering/development/sec/secure/vulnerability-research/) \nengineers, tested prompts in a large language model to see if prompts could yield helpful results. After fine-tuning the prompts, they found that some prompts could provide better details\n and even suggest recommendations for a fix to vulnerabilities related to static application security testing ([SAST](https://docs.gitlab.com/ee/user/application_security/sast/)). \n In a week's time, Product Designer [Becka Lippert](https://gitlab.com/beckalippert) designed a prototype and [Daniel Tian](https://gitlab.com/dftian), \n [Mo Khan](https://gitlab.com/mokhax), and [Neil McCorrison](https://gitlab.com/nmccorrison) built this experimental feature in GitLab.\n\n![Explain and mitigate this vulnerability with AI](https://about.gitlab.com/images/blogimages/2023-04-27-explain-this-vulnerability.png){: .shadow}\n\n\nThis feature is powered by Google AI. Learn more about [our partnership with Google Cloud](https://about.gitlab.com/press/releases/2023-05-02-gitLab-and-google-cloud-partner-to-expand-ai-assisted-capabilities.html) to enrich GitLab features with generative AI.\n\nYou can explore the \"explain this vulnerability\" feature with a [click-through demo](https://go.gitlab.com/0qIe3O).\n\n## Iterating on AI/ML features\n\nThis [experimental](https://docs.gitlab.com/ee/policy/experiment-beta-support.html#experiment) feature is available in GitLab.com today. We are exploring what this feature could look like for \nother types of vulnerabilities beyond SAST and in a merge request. Have an idea that would make this feature better? Please share it with us, along with any feedback, in this \n[issue](https://gitlab.com/gitlab-org/gitlab/-/issues/407295).\n\nThis experiment is just the start of the ways we're looking to infuse GitLab with AI/ML capabilities to help GitLab users become more efficient and effective at their jobs. We are [looking across the software development lifecycle](/blog/what-the-ml-ai/) for painful and time-consuming tasks that are ideal for AI Assisted features. We'll continue to share these demos throughout this blog series.\n\nInterested in using these AI-generated features? [Join our waitlist](https://forms.gle/9eeUkPJauKsbLaoz5) and share your ideas.\n\nContinue reading our ongoing series, \"[AI/ML in DevSecOps](/blog/ai-ml-in-devsecops-series/)\".\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[994,719,9,717],{"slug":1578,"featured":6,"template":698},"explain-this-vulnerability","content:en-us:blog:explain-this-vulnerability.yml","Explain This Vulnerability","en-us/blog/explain-this-vulnerability.yml","en-us/blog/explain-this-vulnerability",{"_path":1584,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1585,"content":1590,"config":1596,"_id":1598,"_type":14,"title":1599,"_source":16,"_file":1600,"_stem":1601,"_extension":19},"/en-us/blog/extending-code-suggestions",{"title":1586,"description":1587,"ogTitle":1586,"ogDescription":1587,"noIndex":6,"ogImage":839,"ogUrl":1588,"ogSiteName":686,"ogType":687,"canonicalUrls":1588,"schema":1589},"ML experiment: Extending Code Suggestions to more development environments","Learn how GitLab is experimenting with extending Code Suggestions to Visual Studio, JetBrains IDE, Neovim, and other environments in our ongoing 'AI/ML in DevSecOps' series.","https://about.gitlab.com/blog/extending-code-suggestions","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"ML experiment: Extending Code Suggestions to more development environments\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kai Armstrong\"}],\n        \"datePublished\": \"2023-06-01\",\n      }",{"title":1586,"description":1587,"authors":1591,"heroImage":839,"date":1593,"body":1594,"category":781,"tags":1595},[1592],"Kai Armstrong","2023-06-01","\n\n\u003Ci>This blog is the latest post in an ongoing series about GitLab's journey to \u003Ca href=\"/blog/ai-ml-in-devsecops-series/\">build and integrate AI/ML into our DevSecOps platform\u003C/a>. The first blog post can be found \u003Ca href=\"/blog/what-the-ml-ai/\">here\u003C/a>. Throughout the series, we'll feature blogs from our product, engineering, and UX teams to showcase how we're infusing AI/ML into GitLab.\u003C/i>\n\nWe've been continuing to [extend the reach](/blog/code-suggestions-for-all-during-beta/) of GitLab Code Suggestions and make [improvements](/blog/code-suggestions-improves-developer-productivity/) to enhance developer productivity. Continuing with our theme of experimentation and iteration, we're now announcing experimental support for Code Suggestions in Visual Studio, JetBrains IDEs, Neovim, and other development environments.\n\n## Code Suggestions for Visual Studio\n\nIn this rapid prototype, [Michael Eddington](https://gitlab.com/mikeeddington), Staff Backend Engineer, built an extension to bring GitLab Code Suggestions to Visual Studio. With this experiment, you can begin writing code and have suggestions provided to help accelerate your development efforts while you type.\n\n![GitLab Code Suggestions in Visual Studio](https://about.gitlab.com/images/blogimages/code-suggestions-visual-studio-ide.gif){: .shadow}\n\nYou can follow our instructions for [getting started](https://gitlab.com/gitlab-org/editor-extensions/experiments/gitlab-code-suggestions-visual-studio-experiment#getting-started) to try this extension out today. Provide your feedback about this extension in [this issue](https://gitlab.com/gitlab-org/editor-extensions/experiments/gitlab-code-suggestions-visual-studio-experiment/-/issues/1).\n\n## Code Suggestions for JetBrains IDEs\n\nIn this rapid prototype, [Dinesh Bolkensteyn](https://gitlab.com/dbolkensteyn), Senior Vulnerability Researcher, built a plugin to bring GitLab Code Suggestions to JetBrains IDE. With this experiment, you can begin writing code and have suggestions provided to help accelerate your development efforts while you type.\n\n![GitLab Code Suggestions in JetBrains IDE](https://about.gitlab.com/images/blogimages/code-suggestions-jetbrains-ide.gif){: .shadow}\n\nYou can follow our instructions for [getting started](https://gitlab.com/gitlab-org/editor-extensions/experiments/gitlab-code-suggestions-jetbrains-experiment#getting-started) to try it out today. Provide your feedback about this extension in [this issue](https://gitlab.com/gitlab-org/editor-extensions/experiments/gitlab-code-suggestions-jetbrains-experiment/-/issues/2).\n\n## Code Suggestions Language Server for Neovim and more\n\nIn this rapid prototype, [Julian Thome](https://gitlab.com/julianthome), Staff Vulnerability Research Engineer, and [Michael Henriksen](https://gitlab.com/mhenriksen), Senior Vulnerability Research Engineeer, developed a language server that leverages the Language Server Protocol to provide GitLab Code Suggestions in Neovim or any other [editor with LSP support](https://microsoft.github.io/language-server-protocol/implementors/tools/). \n\n![GitLab Code Suggestions in Neovim](https://about.gitlab.com/images/blogimages/code-suggestions-neovim.gif){: .shadow}\n\nThis language server allows you to configure any supporting editor or IDE to start receiving GitLab Code Suggestions as you type. We've provided instructions for getting started with [Neovim](https://gitlab.com/gitlab-org/editor-extensions/experiments/gitlab-code-suggestions-language-server-experiment/-/blob/main/docs/nvim.md), [Sublime Text](https://gitlab.com/gitlab-org/editor-extensions/experiments/gitlab-code-suggestions-language-server-experiment/-/blob/main/docs/sublime.md), and [Emacs](https://gitlab.com/gitlab-org/editor-extensions/experiments/gitlab-code-suggestions-language-server-experiment/-/blob/main/docs/emacs.md) for your convenience. Provide your feedback about these integrations in [this issue](https://gitlab.com/gitlab-org/editor-extensions/experiments/gitlab-code-suggestions-language-server-experiment/-/issues/2).\n\n## Iterating on AI/ML features\n\nWhile these are just experiments today, we are iterating on how to effectively bring mature IDE integrations like these to our customers. We'll continue to refine these integrations and improve the experience to provide you with streamlined code suggestions while you work, wherever you choose to work. We're also working to expand our scope beyond these IDEs so if you have an interest in seeing an additional editor/IDE supported, [let us know](https://gitlab.com/groups/gitlab-org/-/epics/2431).\n\nThis experiment is just the start of the ways we're infusing GitLab with AI/ML capabilities to help GitLab users become more efficient and effective at their jobs. We are [looking across the software development lifecycle](/blog/what-the-ml-ai/) for painful and time-consuming tasks that are ideal for AI-assisted features. We'll continue to share these demos throughout this blog series.\n\nInterested in using these AI-generated features? [Join our waitlist](https://forms.gle/9eeUkPJauKsbLaoz5) and share your ideas.\n\nContinue reading our \"[AI/ML in DevSecOps](/blog/ai-ml-in-devsecops-series/)\" series.\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[9,848,719,717],{"slug":1597,"featured":6,"template":698},"extending-code-suggestions","content:en-us:blog:extending-code-suggestions.yml","Extending Code Suggestions","en-us/blog/extending-code-suggestions.yml","en-us/blog/extending-code-suggestions",{"_path":1603,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1604,"content":1610,"config":1616,"_id":1618,"_type":14,"title":1619,"_source":16,"_file":1620,"_stem":1621,"_extension":19},"/en-us/blog/faq-gitlab-ci-cd-catalog",{"title":1605,"description":1606,"ogTitle":1605,"ogDescription":1606,"noIndex":6,"ogImage":1607,"ogUrl":1608,"ogSiteName":686,"ogType":687,"canonicalUrls":1608,"schema":1609},"FAQ: GitLab CI/CD Catalog","Unlock the full potential of the CI/CD Catalog with expert tips and answers to common questions, including how to create and share components.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098783/Blog/Hero%20Images/Blog/Hero%20Images/cicdcover_5vLe737i4QfvAqv6PnqUaR_1750098782745.png","https://about.gitlab.com/blog/faq-gitlab-ci-cd-catalog","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"FAQ: GitLab CI/CD Catalog\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"},{\"@type\":\"Person\",\"name\":\"Dov Hershkovitch\"}],\n        \"datePublished\": \"2024-08-01\",\n      }",{"title":1605,"description":1606,"authors":1611,"heroImage":1607,"date":1613,"body":1614,"category":909,"tags":1615},[1612,1121],"Itzik Gan Baruch","2024-08-01","The [GitLab CI/CD Catalog](https://about.gitlab.com/blog/ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch/), part of the DevSecOps platform, allows users to discover, reuse, and contribute [CI/CD](https://about.gitlab.com/topics/ci-cd/) components to make software development more efficient and productive. Recently, we hosted a CI/CD Catalog webinar that surfaced a host of helpful questions. This FAQ features some of those questions (and answers) and highlights the CI/CD Catalog's capabilities as well as best practices for using it in your environment.\n\n***When will the CI catalog components and inputs be available on Gitlab.com?***\n\nThe [CI catalog components and inputs became generally available](https://about.gitlab.com/blog/ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch/) starting GitLab 17.0 (in GitLab.com and self-managed).  \n\n***What about versioning components? Often a pipeline is coupled with the code, and we want a way to re-run a release pipeline from an older version of the code. Do we have options for version components similarly to how we do the application?***\n\nWe have full support for version control – at any given time you can use any earlier version.\n\n***Can we have composite components that use multiple other components?***\n\nAbsolutely! Here is an example of a deploy component that uses a validate component.\n\n![example of a deploy component that uses validate component](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098788/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098788135.png)\n\n***What are the options for testing components?*** \n\nThere are several methods of testing components. The first method is mentioned in [the documentation](https://docs.gitlab.com/ee/ci/components/examples.html#test-a-component): Including a component using `$CI_COMMIT_SHA` (instead of version), you can test your component for every single commit. Another strategy is to use [child pipelines](https://docs.gitlab.com/ee/ci/pipelines/downstream_pipelines.html#parent-child-pipelines), which allows you to test a component with different inputs parameters. More details can be found in the [GitLab forum](https://forum.gitlab.com/t/ci-cd-component-testing-strategies/102983/2?u=leetickett-gitlab).\n\n***Can the component reference URL use a branch name as the version, similar to how docs show a tag (e.g., $CI_SERVER_FQDN/my-org/security-components/secret-detection@master)?*** \n\nYes, you can use a branch name. [The CI/CD Catalog documentation](https://docs.gitlab.com/ee/ci/components/#component-versions) lists components versions.  \n\n***How can you show the catalog in self-managed instances?***\n\nA self-managed catalog will be available, but will be empty without any published components. You can use this catalog internally in your organization and it is up for you and your teams to populate it with the appropriate components. Alternatively, you can mirror existing components projects from Gitlab.com to your self-managed   instance.\n\n***Can we clone the public repo into a self-hosted instance?*** \n\nA component is hosted in a GitLab project and like any other project it can be cloned locally. Follow these instructions on [how to mirror a component from GitLab.com to self-managed instance](https://docs.gitlab.com/ee/ci/components/#use-a-gitlabcom-component-in-a-self-managed-instance).\n\n***How can you prevent name collisions with CI/CD component jobs?***\n\nUse inputs to specify dynamic job names, which will allow you to [include the same component multiple times in the same pipeline](https://docs.gitlab.com/ee/ci/yaml/inputs.html#include-the-same-file-multiple-times).\n\n***Is it possible to inspect the source code of components in the catalog?***\n\nYes, to view the source code, from the catalog open a component you would like to view. Then, click the component name – this will open the project where the component is hosted and you can find the component’s .yml file in the component's templates folder.\n\n***Can a component receive an array of data as input parameter?***\n\n[A component can receive multiple data types](https://docs.gitlab.com/ee/ci/yaml/?query=inputs#specinputstype) such as string, boolean, number, and array.\n\n***Can the component reference more files alongside the .yml file?***\n\nNo, it can’t. This capability is available in [CI Steps](https://docs.gitlab.com/ee/ci/steps/) (which is experimental).\n\n***Can we have anti-patterns for CI/CD components?***\n\nPlease [follow the best practice section in the documentation](https://docs.gitlab.com/ee/ci/components/#write-a-component).\n\n***Is it possible to limit a group to only using components owned by the group (i.e., not allowing community components)?***\n\nNot yet, but [this feature is on our roadmap](https://gitlab.com/gitlab-org/gitlab/-/issues/441102).\n\n***Is the GitLab CI Steps feature related to this component in any way?***\n\nYes, it is, we consider CI Steps as another type of component. More details can be found in [the CI Steps documentation](https://docs.gitlab.com/ee/ci/steps).\n\n***Is it possible to make private components for your organization only?***\n\nYes, the [component's visibility](https://docs.gitlab.com/ee/ci/components/#view-the-cicd-catalog) is based on the visibility level of your project and only members that have the privileges to see the project can view and search the component in the catalog.\n\n***What is the best approach if I need to fork a Gitlab.com component in terms of GitLab flow to manage the forked repo and propose changes when needed to the original repo?***\n\nYou can manage your fork similarly to how you manage any Git repository – by making changes in your fork and then creating merge requests to propose changes back to the original repository.\n\n***Is there any difference in source code standardization between a verified creator and a non-verified creator in the catalog? Do verified creators have to follow a higher standard?***\n\nCurrently, there is no process to verify and approve individual creators from our extended community. However. we do have a [process for GitLab partners and GitLab-maintained components](https://docs.gitlab.com/ee/ci/components/#verified-component-creators).\n\n***How would you recommend implementing tools like Fortify SCA into your CI/CD pipeline?***\n\nTwo options would be possible: Either Fortify would need to create a shared component in the catalog that exposes the necessary elements for public consumption, or, if publicly-available APIs exist, the community can build an open-source component to be shared and used by others in the catalog.\n\n***What sort of patterns do you recommend for providing \"outputs\" from components that are consumed by other jobs/components in the including pipeline?***\n\nThere is no ability to specify outputs for components, but this is on the roadmap with a new capability called [CI Steps](https://docs.gitlab.com/ee/ci/steps/).\n\n***Is there any plan to label components?***\n\nYes! in this [GitLab epic](https://gitlab.com/groups/gitlab-org/-/epics/11917), we have several issues to enhance searching and discoverability by content type, tags, and category.\n\n***Will existing CI/CD templates be migrated to components?***\n\nYes, the GitLab templates are migrated and have a special badge in the CI/CD Catalog.\n\n***What's the recommended way to transition from our existing GitLab pipeline templates to GitLab catalog components?***\n\nThis should be rather simple since components are very similar to templates. We would recommend start using inputs in your templates, and later on moving them to the appropriate folder structure.\n\n> Learn more about the CI/CD Catalog and components:\n>  \n> - [CI/CD Catalog goes GA: No more building pipelines from scratch](https://about.gitlab.com/blog/ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch/)\n> \n> - [A CI/CD component builder's journey](https://about.gitlab.com/blog/a-ci-component-builders-journey/)\n>\n> - [Documentation: CI/CD components and CI/CD Catalog](https://docs.gitlab.com/ee/ci/components/)\n>\n> - [Introducing CI/CD components and how to use them in GitLab](https://about.gitlab.com/blog/introducing-ci-components/)\n>\n",[109,9],{"slug":1617,"featured":91,"template":698},"faq-gitlab-ci-cd-catalog","content:en-us:blog:faq-gitlab-ci-cd-catalog.yml","Faq Gitlab Ci Cd Catalog","en-us/blog/faq-gitlab-ci-cd-catalog.yml","en-us/blog/faq-gitlab-ci-cd-catalog",{"_path":1623,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1624,"content":1630,"config":1636,"_id":1638,"_type":14,"title":1639,"_source":16,"_file":1640,"_stem":1641,"_extension":19},"/en-us/blog/five-reasons-to-simplify-agile-planning-tool-configuration-gitlab",{"title":1625,"description":1626,"ogTitle":1625,"ogDescription":1626,"noIndex":6,"ogImage":1627,"ogUrl":1628,"ogSiteName":686,"ogType":687,"canonicalUrls":1628,"schema":1629},"5 reasons to simplify your agile planning tool configuration with GitLab","Get more from your agile planning with a platform that supports automation, protects the user experience, and reduces time spent on tool configurations.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665084/Blog/Hero%20Images/agile.png","https://about.gitlab.com/blog/five-reasons-to-simplify-agile-planning-tool-configuration-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"5 reasons to simplify your agile planning tool configuration with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Melissa Ushakov\"}],\n        \"datePublished\": \"2023-10-17\",\n      }",{"title":1625,"description":1626,"authors":1631,"heroImage":1627,"date":1633,"body":1634,"category":1397,"tags":1635},[1632],"Melissa Ushakov","2023-10-17","\nAgile planning tools offer an opportunity to guide team members through a workflow and to follow best practices. In some agile planning tools, like Atlassian Jira, this is done by configuring enforced status workflows for agile planning work items. However, enforced status workflows can slow response times, impact team autonomy, and have other negative effects. Instead, let's explore how a single DevSecOps platform with built-in agile tooling can simplify the process — and how GitLab can help.\n\n## What are enforced status workflows?\nEnforced status workflows define the statuses a work item can be in, the allowed status transitions, the data elements needed to perform a status transition, and which users can perform a status transition. In a typical Jira-user scenario, developers have to manually fill in required data and advance an item through a prescribed status workflow that may not account for exceptions. Enforced workflows in an agile planning tool can limit creativity and unnecessarily block progress when exceptions are encountered, hindering the team's ability to respond swiftly to changing priorities and limiting their autonomy in delivering the best business outcomes.\n\n![status workflows](https://about.gitlab.com/images/blogimages/2023-09-26-say-no-to-complex-status-enforcements-in-your-agile-planning-tool/status_workflow_example.png){: .shadow.small.center}\nExample of an enforced workflow preventing certain status transitions\n{: .note.text-center}\n\n\n## Guiding users through a workflow with GitLab\nHere are five ways GitLab simplifies your agile planning tool configuration.\n\n### 1. Statuses are enforced close to the work for better efficiency.\nCompliance and security checks are necessary, and organizations should ensure that work goes through the proper reviews and that the right team members are involved. Agile planning work items are an artifact that helps align the scope of work of a deliverable, and the work to make that scope a reality happens in downstream in merge requests. Many times, enforcements are better suited to be applied through [approval rules](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/rules.html), [compliance pipelines](https://docs.gitlab.com/ee/user/group/compliance_frameworks.html#compliance-pipelines), or [deployment approvals](https://docs.gitlab.com/ee/ci/environments/deployment_approvals.html). This leads to a greater assurance that the code changes have followed the right process, which matters most. For example, instead of having an enforced status transition in your work items for a security review, you can create [merge request approval rules](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/rules.html), setting the members of your security team as approvers. [Deployment approvals](https://docs.gitlab.com/ee/ci/environments/deployment_approvals.html) can be set up so that your quality assurance lead needs to approve the deployment to specific environments.\n\n![status workflows](https://about.gitlab.com/images/blogimages/2023-09-26-say-no-to-complex-status-enforcements-in-your-agile-planning-tool/unified_approval_rules_v16_0.png){: .shadow.small.center}\nThe production environment requires five total approvals, and allows deployments from only the \"Very Important Group\" and the user administrator.\n{: .note.text-center}\n\n\n### 2. Automation improves data quality.\nThis may seem counterintuitive, but when you place too many restrictions on what data entry is allowed, people stop updating their work items, leading to poor data quality. Working through exceptions to the process is cumbersome, and users need to misreport activity to close the work item when work is done. For example, it's common for users in a tool with workflow enforcements to quickly advance an issue through statuses that didn’t happen so that it could be closed when work has been completed. What if you could intelligently derive the status of work instead of relying on people updating issues? With [GitLab triage](https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage), automation can add or remove labels, set a health status based on downstream DevOps activity, and more. Your developers can spend more time on product innovation and driving your business objectives forward instead of manually updating details, which automation can handle.\n\n![bot labels](https://about.gitlab.com/images/blogimages/2023-09-26-say-no-to-complex-status-enforcements-in-your-agile-planning-tool/gitlab_bot_health.png){: .shadow.medium.center}\nUpdate health with automation\n{: .note.text-center}\n\n\n![bot health](https://about.gitlab.com/images/blogimages/2023-09-26-say-no-to-complex-status-enforcements-in-your-agile-planning-tool/gitlab_bot_labels.png){: .shadow.medium.center}\nUpdate labels with automation\n{: .note.text-center}\n\n\n### 3. The user experience is protected.\nAt GitLab, we prioritize [convention over configuration](https://handbook.gitlab.com/handbook/product/product-principles/#convention-over-configuration) as one of our product principles to deliver exceptional user experiences. This is why GitLab avoids using heavy-handed enforced status workflows in agile planning tools, which end users often dislike. These workflows create friction and hinder your team's productivity. Instead, teams should encourage transparency by explaining the importance of each step in the process, fostering understanding and buy-in. GitLab enables teams to represent a status flow with boards that help to understand the intended flow. A simplified planning tool setup within the DevSecOps platform drives collaboration, transparency, and trust across all roles, leading to a better full-team experience where developers can deliver more value faster.\n\n![workflow board](https://about.gitlab.com/images/blogimages/2023-09-26-say-no-to-complex-status-enforcements-in-your-agile-planning-tool/workflow_board.png){: .shadow.medium.center}\nBoards guide your team through a sequence of statuses\n{: .note.text-center}\n\n\n### 4. Developer tool integration is simplified.\nOrganizations often have a rich ecosystem of tools, and the inability to fully integrate with a critical tool like your agile planning solution limits efficiency and flexibility, potentially leading to time-consuming manual processes. When your status process flow is too restrictive, it is almost impossible to update data from an integration accurately, leading to data mismatches between systems. Other vendors, like Atlassian, have resorted to advising against updating data via an integration. At GitLab, we embrace developer tool preferences and have a comprehensive [suite of APIs and webhooks](https://docs.gitlab.com/ee/api/).\n\n### 5. Time spent on tool configuration is reduced.\nAgile planning tools require close management of configurations. The more prescriptive you make workflows, the more time you have to spend tending to those configurations. With GitLab, automated workflow controls require less effort and enable greater team autonomy. By embracing GitLab's flexible configuration options, teams can spend less time on agile planning tool management and innovate more efficiently.\n\n## Getting started with GitLab\nWith a simplified agile planning tool setup in GitLab that takes advantages of modern DevSecOps practices, you can increase efficiency, encourage collaboration, and get to market faster – all while improving the developer experience.\n\nGet started today with the [Jira importer](https://docs.gitlab.com/ee/user/project/import/jira.html).\n",[1399,496,9,848],{"slug":1637,"featured":6,"template":698},"five-reasons-to-simplify-agile-planning-tool-configuration-gitlab","content:en-us:blog:five-reasons-to-simplify-agile-planning-tool-configuration-gitlab.yml","Five Reasons To Simplify Agile Planning Tool Configuration Gitlab","en-us/blog/five-reasons-to-simplify-agile-planning-tool-configuration-gitlab.yml","en-us/blog/five-reasons-to-simplify-agile-planning-tool-configuration-gitlab",{"_path":1643,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1644,"content":1650,"config":1655,"_id":1657,"_type":14,"title":1658,"_source":16,"_file":1659,"_stem":1660,"_extension":19},"/en-us/blog/five-ways-to-streamline-cloud-adoption",{"title":1645,"description":1646,"ogTitle":1645,"ogDescription":1646,"noIndex":6,"ogImage":1647,"ogUrl":1648,"ogSiteName":686,"ogType":687,"canonicalUrls":1648,"schema":1649},"5 ways to streamline your cloud adoption","As companies migrate to the cloud, consider these helpful tips for making the move smoother and more efficient.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663930/Blog/Hero%20Images/daytime-clouds_1800x945.png","https://about.gitlab.com/blog/five-ways-to-streamline-cloud-adoption","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"5 ways to streamline your cloud adoption\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sharon Gaudin\"}],\n        \"datePublished\": \"2023-09-05\",\n      }",{"title":1645,"description":1646,"authors":1651,"heroImage":1647,"date":1652,"body":1653,"category":10,"tags":1654},[756],"2023-09-05","\nMoving to the cloud makes sense to a lot of companies — it’s getting there that can be difficult.\n\n[GitLab’s 2023 Global DevSecOps Survey](https://about.gitlab.com/developer-survey/) showed that migrating to the cloud can help organizations release software faster: Respondents who were running at least 25% of their applications in the cloud were twice as likely to release software faster than they were a year ago.\n\nHowever, the migration, whether to a single-cloud service or a multi-cloud environment, can be a big lift. IT teams are tasked with securing major data stores and workloads, navigating the complexities of moving legacy applications, and ensuring that cloud environments comply with applicable data regulations and laws. It can be complicated, with a lot of moving pieces that are often difficult to track.\n\nAnd the longer a migration drags on, the more things can go wrong and the more expensive it can get. It only makes sense to look for a way to make something so critical to the business easier, faster, and less expensive.\n\nAbubakar Siddiq Ango, developer evangelism program manager at GitLab, and Fatima Sarah Khalid, developer evangelist at GitLab, share five ways organizations can alleviate some of the time-consuming, repetitive, and arduous tasks it takes to successfully make that move.\n\n## 1. Take care of your data\nOne of the most difficult parts of a cloud migration is moving the data itself – especially if it’s complex and stored across multiple systems – but there are a few ways you can organize and streamline the tasks involved to make them more straightforward. For example, to save time and increase efficiency, Khalid notes that team members can create [issues](https://docs.gitlab.com/ee/user/project/issues/), break tasks down into [milestones](/blog/tackle-nists-plan-of-action-and-milestones-with-gitlabs-risk-management-features/), and use the [Roadmap](https://docs.gitlab.com/ee/user/group/roadmap/) feature, which gives teams a more granular view of their workflow.\n\n## 2. Avoid security pitfalls\n[Security](/blog/its-time-to-put-the-sec-in-devsecops/) should be a key consideration in any cloud migration. Moving to a cloud environment can inadvertently cause misconfigured servers, unsecure APIs, compliance infringements, and data loss. Any of these problems can trip up cloud migration efforts and expose the company to risk.\n\nTo ensure the move to the cloud proceeds smoothly while minimizing security risks, Ango says teams can use [container](https://docs.gitlab.com/ee/user/application_security/container_scanning/) and [dependency scanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/) and [static application security testing](https://docs.gitlab.com/ee/user/application_security/sast/) (SAST) to identify and remediate known vulnerabilities in container images, dependencies, and source code. Teams also can use features such as [code quality](https://docs.gitlab.com/ee/ci/testing/code_quality.html) analysis to supplement existing code review processes and ensure that the project’s code is simple, high-quality, and straightforward to maintain — and, therefore, less likely to cause issues during the migration.\n\n## 3. Automate compliance\n[Compliance](/blog/top-5-compliance-features-to-leverage-in-gitlab/) is another critical issue. IT teams need to ensure the new cloud environment continues to meet all of the organization's regulatory requirements — a potentially large number of standards. That means making sure processes and safeguards focused on data protection are in place and cover the information and applications being moved to the cloud. Manually, that can involve spreadsheets, seemingly endless checklists, and cross-functional teams of people culling through data. Automation makes this more streamlined, requires far fewer people to navigate the process, and is simpler to manage. Automated DevOps practices, like security scanning, [policy automation](/solutions/compliance/), and making compliance standards part of the CI/CD pipeline, all act as guardrails to [keep an organization’s compliance needs on track](/blog/the-importance-of-compliance-in-devops/). With these tools at hand, team members can trust that when they create compliance frameworks and policies, the associated rules will be automatically deployed and enforced throughout the software development lifecycle.\n\n## 4. Relieve configuration challenges\nSetting up and configuring a cloud platform can be a time-consuming and complicated job, but [CI/CD capabilities](/blog/introducing-ci-components/) help automate the configuration process, says Ango. With CI templates, teams can build and deploy applications to different cloud providers or installation targets without having to write their own CI script every time. For instance, [Auto DevOps](https://docs.gitlab.com/ee/topics/autodevops/), a collection of pre-configured features and integrations, uses CI/CD templates to handle deployments on each different cloud environment.\n\nThe [GitLab agent for Kubernetes](https://docs.gitlab.com/ee/user/clusters/agent/install/) also can offer integration capabilities for different cloud providers and services. The agent, which helps set up GitOps, automatically deploys workloads to Kubernetes clusters. Any time new changes are made, it pulls them in and deploys them into a cluster.\nAlso, teams can use [GitLab and Terraform for infrastructure as code](https://docs.gitlab.com/ee/user/infrastructure/iac/), removing the complexities of making configuration changes repeatable, traceable, and more scalable, which is essential for cloud environments.\n\n## 5. Go multi-cloud\nWhile some companies are making initial moves to the cloud, others are expanding from a single cloud to a multi-cloud environment. This strategy enables organizations to run different workloads on different cloud platforms. Being cloud agnostic means they can use the same development tools and internal processes, and then choose where they want to have their workloads run based on their business needs. Problems can arise, though, when IT teams turn to vendor-locked, cloud native developer tools, which are tailored to their own services and might, or might not, support other cloud environments. Using different tools for each cloud platform isn’t efficient, so it’s key to find tools that are cloud or provider agnostic.\n\n## Uncomplicate cloud migration with a DevSecOps platform\nYes, there are different ways to ease a cloud migration – but do teams have to go out and round up a dozen different tools to ensure their migration is fast, secure, and compliant? No, they don't.\n\n“A lot of teams are realizing that having a single, unified place to simplify, automate, and manage the process of setting up or migrating to the cloud is a game changer,” says Khalid. “With an end-to-end [DevSecOps platform](/blog/utilize-the-gitlab-devops-platform-to-avoid-cloud-migration-hazards/), users are able to deploy to any of the common public clouds; support collaboration through features like merge requests, code reviews, and issue tracking; support integrations with a variety of third-party tools; and have built-in security features that allow teams to meet their needs.”\n\nTaking advantage of the GitLab DevSecOps Platform can uncomplicate a lot of those adoption challenges. And GitLab works with any cloud provider.\n\n“I know when people think about the GitLab platform, they focus on security, source code management, and [collaboration](/blog/5-ways-collaboration-boosts-productivity-and-your-career/). But we also really should be thinking about how it’s a tool that helps organizations get their [workload to the cloud](/blog/shifting-from-on-prem-to-cloud/),” says Ango. “You have to be able to work fast, move fast and deploy fast on whatever cloud environment you need, and do it all securely. That is what GitLab offers. That is a big deal.”\n\n_To find the features — all in one place — that your organization needs to ease and speed a cloud migration, check out this [free trial of GitLab Ultimate](https://about.gitlab.com/free-trial/devsecops/)._\n",[9,953,825,826],{"slug":1656,"featured":6,"template":698},"five-ways-to-streamline-cloud-adoption","content:en-us:blog:five-ways-to-streamline-cloud-adoption.yml","Five Ways To Streamline Cloud Adoption","en-us/blog/five-ways-to-streamline-cloud-adoption.yml","en-us/blog/five-ways-to-streamline-cloud-adoption",{"_path":1662,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1663,"content":1669,"config":1675,"_id":1677,"_type":14,"title":1678,"_source":16,"_file":1679,"_stem":1680,"_extension":19},"/en-us/blog/getting-started-with-gitlab-application-security",{"title":1664,"description":1665,"ogTitle":1664,"ogDescription":1665,"noIndex":6,"ogImage":1666,"ogUrl":1667,"ogSiteName":686,"ogType":687,"canonicalUrls":1667,"schema":1668},"Getting started with GitLab application security","This tutorial shows how to incorporate GitLab security scan templates into a .gitlab-ci.yml file and view scan results.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663993/Blog/Hero%20Images/2018-developer-report-cover.jpg","https://about.gitlab.com/blog/getting-started-with-gitlab-application-security","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Getting started with GitLab application security\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Victor Hernandez\"},{\"@type\":\"Person\",\"name\":\"Julie Byrne\"}],\n        \"datePublished\": \"2023-03-15\",\n      }",{"title":1664,"description":1665,"authors":1670,"heroImage":1666,"date":1672,"body":1673,"category":909,"tags":1674},[1671,736],"Victor Hernandez","2023-03-15","As software security becomes increasingly important, many companies want to\nintroduce standard code scanning processes into development workflows to\nfind and remediate security vulnerabilities before they get to production.\nGitLab's DevSecOps Platform allows users to perform security scans in CI/CD\npipelines, which can easily be enabled to check applications for security\nvulnerabilities such as unauthorized access, data leaks, and denial of\nservice (DoS) attacks. While most of what is covered in this blog will\npertain to Ultimate features, there are some features available for free and\nPremium tier users as well. By the end of this blog, you will have a solid\nstarting point for adopting GitLab security scans, with any tier license,\nand understand the steps to take next to mature your DevSecOps practices.\n\n\n## Prerequisites\n\nTo enable security scanning for a project, you must have the following:\n\n- a GitLab project that meets the requirements of the security scan you\nchoose to enable, with CI enabled\n\n- a `.gitlab-ci.yml` file for the project that has at least a build job\ndefined\n\n- a Linux-based GitLab Runner with the Docker or Kubernetes executor\n\n\n## Get started: Add a scan template to your pipeline\n\n\nHere are the first steps to introduce security scanning.\n\n\n### Available security scans\n\n\nGitLab provides a variety of security scanners, each with its own set of\ncriteria for adoption:\n\n\n| Scan type | Minimum tier | Prerequisites | Application requirements |\n\n| --- | --- | --- | --- |\n\n| [Static application security testing\n(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) | Free |\nNone | See [SAST\nrequirements](https://docs.gitlab.com/ee/user/application_security/sast/index.html#requirements)\n|\n\n| [Secret\ndetection](https://docs.gitlab.com/ee/user/application_security/secret_detection/)\n| Free | None | None |\n\n| [Container\nscanning](https://docs.gitlab.com/ee/user/application_security/container_scanning/)\n| Free | Container image built and pushed to registry | [Docker 18.09.03 or\nhigher installed on the same computer as the\nrunner](https://docs.gitlab.com/ee/user/application_security/container_scanning/index.html#requirements);\nimage uses a [supported\ndistribution](https://docs.gitlab.com/ee/user/application_security/container_scanning/index.html#supported-distributions)\n|\n\n| [Infrastructure as code (IaC)\nscanning](https://docs.gitlab.com/ee/user/application_security/iac_scanning/)\n|  Free | None | See [supported languages and\nframeworks](https://docs.gitlab.com/ee/user/application_security/iac_scanning/#supported-languages-and-frameworks)\n|\n\n| [Dependency\nscanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/)\n- includes license compliance | Ultimate | None | Application must use one\nof the [supported languages and package\nmanagers](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/index.html#supported-languages-and-package-managers)\n|\n\n| [Dynamic application security testing\n(DAST)](https://docs.gitlab.com/ee/user/application_security/dast/) |\nUltimate | [Deployed target\napplication](https://docs.gitlab.com/ee/user/application_security/dast/index.html#prerequisites)\n| See [GitLab DAST scanning\noptions](https://docs.gitlab.com/ee/user/application_security/dast/index.html#gitlab-dast)\n|\n\n| [Coverage-guided fuzz\ntesting](https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing/)\n| Ultimate | Instrumented version of application | See [supported fuzzing\nengines and\nlanguages](https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing/index.html#supported-fuzzing-engines-and-languages)\n|\n\n| [Web API fuzz\ntesting](https://docs.gitlab.com/ee/user/application_security/api_fuzzing/)\n|  Ultimate | Deployed target application | See [supported API\ntypes](https://docs.gitlab.com/ee/user/application_security/api_fuzzing/#enable-web-api-fuzzing)\n|\n\n\nMany customers will start with secret detection, dependency scanning, or\nSAST scanning, as they have the fewest requirements for usage.\n\n\n### Add the scanner template\n\n\nGitLab provides a [CI template for each security\nscan](https://docs.gitlab.com/ee/user/application_security/#security-scanning-without-auto-devops)\nthat can be added to your existing `.gitlab-ci.yml` file. This can be done\nby manually editing the CI file and adding the appropriate template path in\nthe templates section of the file. Several scanners can also be [enabled via\nthe\nUI](https://docs.gitlab.com/ee/user/application_security/sast/#configure-sast-in-the-ui),\nwhere a merge request will be created to add the appropriate scanner to the\n`.gitlab-ci.yml` file. \n\n\nI will use a simple spring boot application as an example and enable\ndependency scanning, a scanner that is popular amongst our customers, as my\nfirst security scan. Dependency scanning will find vulnerabilities in the\nlibraries I am using to build my application. My project is a Java\napplication built via Maven and includes a `pom.xml` file, so it meets the\nrequirements for dependency scanning. Since dependency scanning can be\nenabled via the UI, I'm going to take advantage of that feature here. \n\n\nFor this project, I have created a `.gitlab-ci.yml` file that contains a\nbuild and test stage and a build job. I'm using the Auto DevOps auto-build\njob, but you can define your own build job if desired. This is the starting\npipeline code in my `.gitlab-ci.yml` file:\n\n\n```\n\nimage: alpine:latest\n\n\ninclude:\n  - template: Jobs/Build.gitlab-ci.yml  # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml\n\nstages:\n\n- build\n\n- test\n\n\n```\n\n\nTo enable dependency scanning, I'll first navigate to the **Security &\nCompliance** menu, **Configuration** sub-menu.\n\n\n![web\nidentity](https://about.gitlab.com/images/blogimages/2023-02-26-getting-started-with-gitlab-application-security/security_config.png){:\n.shadow}\n\n\nThe option to enable dependency scanning is available about halfway down the\npage. When I click `Configure with a merge request`, a branch is created and\nI am prompted to create a corresponding draft merge request. I'll click\n`Create Merge Request` to save the merge request.\n\n\nOnce the merge request has been created, I see that a new branch\n`set-dependency-scanning-config-1` has been created and the `.gitlab-ci.yml`\nfile has been updated with this code:\n\n\n```\n\n# You can override the included template(s) by including variable overrides\n\n# SAST customization:\nhttps://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings\n\n# Secret Detection customization:\nhttps://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings\n\n# Dependency Scanning customization:\nhttps://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings\n\n# Container Scanning customization:\nhttps://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings\n\n# Note that environment variables can be set in several places\n\n# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence\n\nimage: alpine:latest\n\ninclude:\n\n- template: Jobs/Build.gitlab-ci.yml\n\n- template: Security/Dependency-Scanning.gitlab-ci.yml\n\nstages:\n\n- build\n\n- test\n\n\n```\n\n\nThe change kicks off a pipeline, which will now include the dependency scan.\n\n\n![web\nidentity](https://about.gitlab.com/images/blogimages/2023-02-26-getting-started-with-gitlab-application-security/dependency_job.png){:\n.shadow}\n\n\n## View results of the security scan\n\n\nFor all license tiers, you can view the results of any security scan jobs in\nthe appropriate JSON report that can be downloaded from the merge request.\n\n\n![web\nidentity](https://about.gitlab.com/images/blogimages/2023-02-26-getting-started-with-gitlab-application-security/mr_artifacts.png){:\n.shadow}\n\n\nWith GitLab Ultimate, you will also see the vulnerabilities found by the\nscan in the merge request widget.\n\n\n![web\nidentity](https://about.gitlab.com/images/blogimages/2023-02-26-getting-started-with-gitlab-application-security/mr_widget.png){:\n.shadow}\n\n\nAt this point, the `.gitlab-ci.yml` changes that enable security scanning\nare only available in the `set-dependency-scanning-config-1` branch. I will\nmerge them to `main` so that the changes will be included in all future\nfeature branches.\n\n\nWith GitLab Ultimate, merging to `main` will also provide the baseline\n**Vulnerability Report** for our application.  \n\n\n![web\nidentity](https://about.gitlab.com/images/blogimages/2023-02-26-getting-started-with-gitlab-application-security/vuln_report.png){:\n.shadow}\n\n\nNow, scan results presented in the merge request widget for any new merge\nrequests will only show vulnerabilities introduced by those new code changes\nin the corresponding feature branch, and not the baseline of vulnerabilities\nthat already exist on `main`.\n\n\n## Scan enforcement\n\n\nOnce you have enabled your first scans in your CI/CD pipelines, you might be\ncurious to know how you can enforce security scans, or enforce a review and\napproval when critical vulnerabilities are found in new code changes. I\nrecommend reviewing these resources that cover these topics. \n - For Ultimate customers: [How to ensure separation of duties and enforce compliance with GitLab](/blog/ensuring-compliance/)\n - For Premium customers: [How to action security vulnerabilities in GitLab Premium](https://about.gitlab.com/blog/actioning-security-vulnerabilities-in-gitlab-premium/)\n\nNow that you've gained comfort with security scanners as part of the GitLab\nCI/CD pipeline, check out our [Getting Started with GitLab Application\nSecurity](https://docs.gitlab.com/ee/user/application_security/get-started-security.html)\ndocumentation for recommended next steps.\n\n\n## More resources\n - [How GitLab's application security dashboard helps AppSec engineers](/blog/secure-stage-for-appsec/)\n - [Running security scans in limited connectivity and offline environments](/blog/offline-environments/)\n - [GitLab's newest continuous compliance features bolster software supply chain security](/blog/gitlabs-newest-continuous-compliance-features-bolster-software/)\n",[9,825,826,694],{"slug":1676,"featured":6,"template":698},"getting-started-with-gitlab-application-security","content:en-us:blog:getting-started-with-gitlab-application-security.yml","Getting Started With Gitlab Application Security","en-us/blog/getting-started-with-gitlab-application-security.yml","en-us/blog/getting-started-with-gitlab-application-security",{"_path":1682,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1683,"content":1689,"config":1694,"_id":1696,"_type":14,"title":1697,"_source":16,"_file":1698,"_stem":1699,"_extension":19},"/en-us/blog/github-to-gitlab-migration-made-easy",{"title":1684,"description":1685,"ogTitle":1684,"ogDescription":1685,"noIndex":6,"ogImage":1686,"ogUrl":1687,"ogSiteName":686,"ogType":687,"canonicalUrls":1687,"schema":1688},"GitHub to GitLab migration the easy way","Learn how easy it is to migrate from GitHub to GitLab using GitLab's project import functionality.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749668776/Blog/Hero%20Images/julia-craice-faCwTallTC0-unsplash.jpg","https://about.gitlab.com/blog/github-to-gitlab-migration-made-easy","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitHub to GitLab migration the easy way\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Fernando Diaz\"}],\n        \"datePublished\": \"2023-07-11\",\n      }",{"title":1684,"description":1685,"authors":1690,"heroImage":1686,"date":1691,"body":1692,"category":10,"tags":1693},[1533],"2023-07-11","If you are using different CI/CD tools and are considering migrating over to\nGitLab, you may be wondering about\n\nthe difficulty of the migration process. Migration is usually a concern for\n[DevSecOps](https://about.gitlab.com/topics/devsecops/) teams when\nconsidering a new solution. This is due to the fact that migrating may\ninvolve heavy lifting. However, migrating to the GitLab AI-powered DevSecOps\nPlatform can be extremely simple and I will show you how step by step. \n\n\nIn this blog post, we will go over how to migrate from GitHub to GitLab\nusing our [project import](https://docs.gitlab.com/ee/user/project/import/)\nfunctionality. Manually migrating GitHub Actions to GitLab pipelines will be\ncovered as well. I have also created a video going over the migration\nprocess for those who prefer that format:\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/0Id5oMl1Kqs\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n## What data can be migrated from GitHub to GitLab?\n\nGitLab's built-in importer allows for GitHub projects to be automatically\nmigrated into GitLab. The built-in importer\n\nis accessed directly from GitLab's project creation UI. From the UI, you can\nselect what data you wish to migrate to GitLab.\n\n\nThe data that can be migrated includes the following:\n\n* Repository description\n\n* Git repository data\n\n* Branch protection rules\n\n* Collaborators (members)\n\n* Issues\n\n* Pull requests\n\n* Wiki pages\n\n* Milestones\n\n* Labels\n\n* Release notes content\n\n* Release notes attachments\n\n* Comment attachments\n\n* Issue description attachments\n\n* Pull request description attachments\n\n* Pull request review comments\n\n* Regular issue and pull request comments\n\n* Git Large File Storage (LFS) objects\n\n* Pull request reviews\n\n* Pull request assigned reviewers\n\n* Pull request “merged by” information\n\n* Pull request comments replies in discussions\n\n* Pull request review comments suggestions\n\n* Issue events and pull requests events\n\n\nGitHub and GitLab have different naming conventions and concepts, so a\nmapping must be performed during the migration. For example, when\ncollaborators/members are migrated, roles from GitHub are mapped to the\nappropriate GitLab roles as follows:\n\n\n| GitHub role | GitLab role |\n\n| ----------- | ----------- |\n\n| Read        | Guest       |\n\n| Triage      | Reporter    |\n\n| Write       | Developer   |\n\n| Maintain    | Maintainer  |\n\n| Admin       | Owner       |\n\n\n## Prerequisites\n\nNow that you have an understanding of what can be imported, let's review the\nprerequisites for performing the migration.\n\n\nWith the GitLab importer, you can either import your projects from\n**GitHub.com** or **GitHub Enterprise** to either **GitLab.com** or\n**Self-managed GitLab** as long as you meet the following requirements:\n\n* You must be a Maintainer on the GitLab destination group you are importing\nto from GitHub\n\n* Each GitHub author and assignee in the repository must have a\npublic-facing email address on GitHub that matches their GitLab email\naddress\n\n* GitHub accounts must have a public-facing email address that is populated\n\n* [GitHub import\nsource](https://docs.gitlab.com/ee/administration/settings/visibility_and_access_controls.html#configure-allowed-import-sources)\nmust be enabled (Self-managed GitLab only)\n\n\nWhen migrating a user, GitLab uses the public-facing email address in GitHub\nto verify the user with the same email on GitLab. Because email ownership is\nunique, you'll know you have set a valid user with valid permissions.\n\n\n## Performing the import\n\nNow let's go over how to perform the migration. I will be migrating my\nproject, the [Reddit sentiment\nanalyzer](https://github.com/fishtoadsoft/reddit-sentiment-analyzer), from\nGitHub to GitLab. The Reddit sentiment analyzer contains a pull request\n(called a merge request in GitLab), issues, and comments. \n\n\n**Note:** While you may not have permissions to my project, the step-by-step\nprocess applies to any project you own. I am using my project so you can see\nhow I migrate GitHub Actions in the next section. Now, let's get started!\n\n\n1) Create a new project in GitLab using the [Project Creation\nInterface](https://gitlab.com/projects/new).\n\n\n2) Select the **Import Project** box. This allows you to migrate data from\nexternal sources.\n\n\n![Import project\nbox](https://about.gitlab.com/images/blogimages/2023-july-github-to-gitlab-migration/import_project.png)\n\n\n3) Under **Import project from**, press the **GitHub** button. This will\ntake you to the **Authenticate with GitHub** page.\n\n\n4) Press the **Authenticate with GitHub** button. You can also use a\n[personal access\ntoken](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)\nfrom GitHub with the **repo scope** if you prefer. This will take you to the\nGitHub authorization app.\n\n\n5) From here, you can grant access to [GitHub\norganization(s)](https://docs.github.com/en/organizations/collaborating-with-groups-in-organizations/about-organizations)\nwhere the projects you wish to migrate are located.\n\n\n![GitHub authorization\napp](https://about.gitlab.com/images/blogimages/2023-july-github-to-gitlab-migration/github_authorize_app.png)\n\n\n6) Press the **Grant** button for the organization where the project you\nwish to migrate is stored.\n\n\n7) Press the **Authorize gitlabhq** button to grant GitLab access to the\norganization(s) selected. You will then be taken to the import selection\npage.\n\n\n8) From here, you can select the items you wish to import. \n\n\n![Import\nselection](https://about.gitlab.com/images/blogimages/2023-july-github-to-gitlab-migration/import_selection.png)\n\n\n**Note:** The more items you choose to migrate, the longer the import will\ntake.\n\n\n9) Then you must set the GitLab location you want to migrate the GitHub\nproject to.\n\n\n![Set the GitLab location to migrate\nto](https://about.gitlab.com/images/blogimages/2023-july-github-to-gitlab-migration/import_to.png)\n\n\n10) Press the **Import** button and the import will begin. You can see the\nprogress in the UI. Once the import is complete the status will be changed\nto \"complete.\"\n\n\n[Import progress\nstatus](/images/blogimages/2023-july-github-to-gitlab-migration/import_progress.png)\n\n\nNow you should have the imported project in your workspace. Mine is called\n[https://gitlab.com/awkwardferny/reddit-sentiment-analyzer](https://gitlab.com/awkwardferny/reddit-sentiment-analyzer).\nWhen examining the imported project, you can see the following:\n\n\n**Repository has been migrated**\n\n\n![Repository has been\nmigrated](https://about.gitlab.com/images/blogimages/2023-july-github-to-gitlab-migration/migrated_data.png)\n\n\n**Issue has been migrated**\n\n\n![Issue has been\nmigrated](https://about.gitlab.com/images/blogimages/2023-july-github-to-gitlab-migration/migrated_issue.png)\n\n\n**Merge request has been migrated**\n\n\n![Merge request has been\nmigrated](https://about.gitlab.com/images/blogimages/2023-july-github-to-gitlab-migration/migrated_merge_request.png)\n\n\n## Migrating GitHub Actions over to GitLab CI/CD\n\nNow that you have migrated the project over from GitHub, notice that none of\nthe GitHub Actions are running. Don't worry, they are very easy to migrate\nmanually. So let's start the migration process for Actions.\n\n\n1) Examine the GitHub Actions within the **.github/workflows** folder. In\nthe [project you just\nimported](https://gitlab.com/awkwardferny/reddit-sentiment-analyzer/-/tree/master/.github/workflows),\nyou should see three different Action files:\n\n\n#### lint.yml\n\nThis file contains the Action, which performs linting on the source code\nusing flake8. It uses the python:3.10 Docker image and installs the\napplication requirements before performing the lint.\n\n\n```yaml\n\nname: \"Lint\"\n\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v3\n    - name: Set up Python 3.10\n      uses: actions/setup-python@v4\n      with:\n        python-version: \"3.10\"\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install flake8 pytest\n        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n    - name: Lint with flake8\n      run: |\n        # stop the build if there are Python syntax errors or undefined names\n        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics\n        # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide\n        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics\n```\n\n\n#### smoke.yml\n\nThis file contains the action which performs a smoke test by just running\nthe CLI help menu. It uses the python:3.10 Docker image and installs the\napplication requirements before performing the smoke test.\n\n\n```yaml\n\nname: \"Smoke Tests\"\n\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  smoke-tests:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v3\n    - name: Set up Python 3.10\n      uses: actions/setup-python@v4\n      with:\n        python-version: \"3.10\"\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install setuptools\n        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n    - name: Install Sentiment Analysis Application\n      run: |\n        python setup.py install\n    - name: Run smoke tests\n      run: |\n        reddit-sentiment --help\n```\n\n\n#### unit.yml\n\nThis file contains the Action, which performs unit tests using pytest. It\nuses the python:3.10 Docker image and installs the application requirements\nrunning the unit tests.\n\n\n```yaml\n\nname: \"Unit Tests\"\n\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  unit-tests:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v3\n    - name: Set up Python 3.10\n      uses: actions/setup-python@v4\n      with:\n        python-version: \"3.10\"\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install pytest\n        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n    - name: Test with pytest\n      run: |\n        python -m pip install --upgrade pip\n        if [ -f test-requirements.txt ]; then pip install -r test-requirements.txt; fi\n        pytest tests/\n```\n\n\nNow let's go ahead and migrate these Actions over to GitLab.\n\n\n2) Go to the recently imported project on GitLab and open up the\n[WebIDE](https://docs.gitlab.com/ee/user/project/web_ide/).\n\n\n3) Create a file at the root called\n[**.gitlab-ci.yml**](https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html).\n\nThis file defines the GitLab pipeline.\n\n\n4) Add the following configuration, which will add the GitHub Actions as\nJobs in the GitLab pipeline. Notice the comments I added describing each\nsection.\n\n\n```yaml\n\n# This creates the stages in which the jobs will run. By default all\n\n# jobs will run in parallel in the stage. Once the jobs are completed\n\n# successfully then you move on to the next stage. The way jobs run\n\n# is completely configurable.\n\nstages:\n  - test\n\n# With the include statement, you can quickly add jobs which have\n\n# been pre-defined in external YAMLs. The SAST job I included below\n\n# is provided and maintained by GitLab and adds Static Application\n\n# Security Testing (SAST) to your pipeline.\n\ninclude:\n  - template: Jobs/SAST.gitlab-ci.yml\n\n# This is the unit test job which does exactly what is defined in\n\n# the GitHub Action in unit.yml. You can see it uses the python:3.10\n\n# Docker image, installs the application dependencies, and then runs\n\n# the unit tests with pytest. It was added with a simple copy and\n\n# paste and minor syntax changes.\n\nunit:\n  image: python:3.10\n  stage: test\n  before_script:\n    - python -m pip install --upgrade pip\n    - pip install pytest\n    - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n  script:\n    - pytest tests/\n\n# This is the lint job which does exactly what is defined in the\n\n# GitHub Action in lint.yml. You can see it uses the python:3.10\n\n# Docker image, installs the application dependencies, and then\n\n# performs the linting with flake8. It was added with a simple copy\n\n# and paste and minor syntax changes.\n\nlint:\n  image: python:3.10\n  stage: test\n  before_script:\n    - python -m pip install --upgrade pip\n    - pip install flake8\n    - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n  script:\n    - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics\n    - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics\n\n# This is the smoke test job which does exactly what is defined in\n\n# the GitHub Action in smoke.yml. You can see it uses the python:3.10\n\n# Docker image, installs the application dependencies, and then runs\n\n# the smoke tests with the Reddit sentiment analysis CLI. It was\n\n# added with a simple copy and paste and minor syntax changes.\n\nsmoke:\n  image: python:3.10\n  stage: test\n  before_script:\n    - python -m pip install --upgrade pip\n    - pip install setuptools\n    - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n    - python setup.py install\n  script:\n    - reddit-sentiment --help\n```\n\n\nYou can see that scripts being executed in GitLab match those scripts within\nthe GitHub Actions. The only thing that has really changed is the syntax\nsetting up the jobs and stages. To learn more on how to create and configure\npipelines, check out the [GitLab CI/CD\ndocumentation](https://docs.gitlab.com/ee/ci/).\n\n\n5) Let's check in the code. From the WebIDE click on the Source Control Tab\nin the side panel of the WebIDE. It is the [third icon from the\ntop](https://code.visualstudio.com/docs/sourcecontrol/overview#_commit).\nThen press the **Commit to 'main'** button, select **Continue**, and voila,\nyou should now have a running pipeline.\n\n\n6) Examine the pipeline and make sure the jobs are running properly. Go back\nto your project and click on the\n[pipeline](https://docs.gitlab.com/ee/ci/pipelines/) icon. You can see the\nthe four jobs we created have run.\n\n\n![Four jobs have\nrun](https://about.gitlab.com/images/blogimages/2023-july-github-to-gitlab-migration/gitlab_jobs.png)\n\n\n7) Click on the **Unit** job and you can see that the unit tests were run\nsuccessfully.\n\n\n```bash\n\n$ pytest tests/\n\n============================= test session starts\n==============================\n\nplatform linux -- Python 3.10.11, pytest-7.3.1, pluggy-1.0.0\n\nrootdir: /builds/awkwardferny/reddit-sentiment-analyzer\n\ncollected 2 items\n\ntests/test_scraper.py ..                                                \n[100%]\n\n============================== 2 passed in 0.09s\n===============================\n\nCleaning up project directory and file based variables\n\n00:00\n\nJob succeeded\n\n```\n\n\nAnd that's how simple it is to migrate a project over from GitHub to GitLab!\n\n\n## What other platforms can GitLab import from?\n\nThe GitLab importer allows one-click migration from several other platforms.\nThese platforms include:\n\n* [Bitbucket\nCloud](https://docs.gitlab.com/ee/user/project/import/bitbucket.html)\n\n* [Bitbucket Server\n(Stash)](https://docs.gitlab.com/ee/user/project/import/bitbucket_server.html)\n\n* [FogBugz](https://docs.gitlab.com/ee/user/project/import/fogbugz.html)\n\n* [Gitea](https://docs.gitlab.com/ee/user/project/import/gitea.html)\n\n* [Repository by\nURL](https://docs.gitlab.com/ee/user/project/import/repo_by_url.html)\n\n* [Uploading a manifest file\n(AOSP)](https://docs.gitlab.com/ee/user/project/import/manifest.html)\n\n* [Jira (issues\nonly)](https://docs.gitlab.com/ee/user/project/import/jira.html)\n\n\nWe also have documentation covering how to migrate from these platforms:\n\n*\n[SVN](https://docs.gitlab.com/ee/user/project/import/#import-from-subversion)\n\n* [ClearCase](https://docs.gitlab.com/ee/user/project/import/clearcase.html)\n\n* [CVS](https://docs.gitlab.com/ee/user/project/import/cvs.html)\n\n* [Perforce](https://docs.gitlab.com/ee/user/project/import/perforce.html)\n\n* [TFVC](https://docs.gitlab.com/ee/user/project/import/tfvc.html)\n\n\n---\n\n\nThanks for reading! Now you know how easy it is to migrate from GitHub over\nto GitLab. For more information on GitLab\n\nand migrating from GitHub, follow the links below:\n\n\n* [GitHub-to-GitLab project migration\ndocumentation](https://docs.gitlab.com/ee/user/project/import/github.html)\n\n* [Available project\nimporters](https://docs.gitlab.com/ee/user/project/import/#available-project-importers)\n\n* [GitHub-to-GitLab migration video](https://youtu.be/0Id5oMl1Kqs)\n\n\nAlso, read how GitLab has been named a leader in the DevOps platforms space\nby\n[Gartner](https://about.gitlab.com/blog/gitlab-leader-gartner-magic-quadrant-devops-platforms/)\nand the integrated software delivery platforms space by\n[Forrester](https://about.gitlab.com/blog/gitlab-leader-forrester-wave-integrated-software-delivery-platforms/).\n\n\n_Cover image by [Julia\nCraice](https://unsplash.com/@jcraice?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\non\n[Unsplash](https://unsplash.com/s/photos/migration?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)_\n",[109,827,9,496],{"slug":1695,"featured":6,"template":698},"github-to-gitlab-migration-made-easy","content:en-us:blog:github-to-gitlab-migration-made-easy.yml","Github To Gitlab Migration Made Easy","en-us/blog/github-to-gitlab-migration-made-easy.yml","en-us/blog/github-to-gitlab-migration-made-easy",{"_path":1701,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1702,"content":1708,"config":1715,"_id":1717,"_type":14,"title":1718,"_source":16,"_file":1719,"_stem":1720,"_extension":19},"/en-us/blog/gitlab-advanced-sast-is-now-generally-available",{"title":1703,"description":1704,"ogTitle":1703,"ogDescription":1704,"noIndex":6,"ogImage":1705,"ogUrl":1706,"ogSiteName":686,"ogType":687,"canonicalUrls":1706,"schema":1707},"GitLab Advanced SAST is now generally available","Reduce false positives, shorten remediation time, and improve development velocity with a proprietary solution built into GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665917/Blog/Hero%20Images/blog-advanced-sast-creative-imagery-0390-1800x945-fy25.png","https://about.gitlab.com/blog/gitlab-advanced-sast-is-now-generally-available","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab Advanced SAST is now generally available\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Salman Ladha\"},{\"@type\":\"Person\",\"name\":\"Connor Gilbert\"}],\n        \"datePublished\": \"2024-09-19\",\n      }",{"title":1703,"description":1704,"authors":1709,"heroImage":1705,"date":1712,"body":1713,"category":694,"tags":1714},[1710,1711],"Salman Ladha","Connor Gilbert","2024-09-19","We’re excited to announce that our Advanced Static Application Security Testing (SAST) scanner is now generally available for all GitLab Ultimate customers. \n\nAdvanced SAST is a new scanner powered by the technology we [acquired from Oxeye](https://about.gitlab.com/blog/oxeye-joins-gitlab-to-advance-application-security-capabilities/) earlier this year. It uses a proprietary detection engine with rules informed by in-house security research to identify exploitable vulnerabilities in first-party code. It delivers more accurate results so developers and security teams don’t have to sort through the noise of false-positive results.\n\nUnlike other stand-alone security scanners, Advanced SAST is natively built into the GitLab DevSecOps platform, providing a developer experience free from the overhead that comes with integrating multiple point solutions. Using taint analysis, relevant context is surfaced to help developers remediate vulnerabilities within their existing workflow to maximize development velocity and application security. \n\nThis new scanner will work alongside our existing platform capabilities so developers and application security (AppSec) teams have the most comprehensive set of tools to ship more secure software, faster. \n\n## Applications are being developed faster but remain vulnerable \n\nThe pace of application development continues to accelerate, but remains a common attack vector for threat actors. Our recent [Global DevSecOps Report](https://about.gitlab.com/developer-survey/) found that 66% of companies are releasing software twice as fast — or faster — than in previous years, as businesses strive to deliver more value to their customers than competitors.\n\nHowever, speed introduces risk. Last year alone, [80% of the top data breaches](https://www.crowdstrike.com/2024-state-of-application-security-report/) stemmed from attacks at the application layer.\n\nThese two data points paint a clear picture: Application security tools must be built into existing developer workflows so businesses can stay competitive and secure. \n\n## What are SAST and Advanced SAST?  \n\nSAST is a [widely adopted method for improving application security](https://about.gitlab.com/developer-survey/) by scanning first-party source code to identify vulnerabilities, such as SQL injections or cross-site scripting, before they reach production. Unlike its dynamic counterpart, [DAST](https://about.gitlab.com/topics/devsecops/sast-vs-dast/), SAST scans code without executing it and is performed early in the software development lifecycle (SDLC). This proactive approach integrates security into the development process from the outset, significantly lowering the risk of future breaches.\n\n> Check out this [step-by-step tutorial](https://about.gitlab.com/blog/quick-vulnerability-remediation-with-gitlab-advanced-sast-duo-ai/) to put Advanced SAST to work in your environment.\n\n### Fewer false positives with contextual remediation\n\nThe integration of Oxeye’s technology into our platform means we’re able to provide a SAST solution AppSec teams can trust, built into the same GitLab platform developers love. Here’s how we’re able to do that and what it means for our customers: \n\n**Less time triaging vulnerabilities and more time launching features** \n* Our proprietary detection engine uses cross-function, cross-file taint analysis with rules informed by in-house security research to surface truly exploitable vulnerabilities and improve scan accuracy — that means lower false-positive rates. \n\n**Faster remediation with richer context** \n* Advanced SAST helps developers remediate security vulnerabilities by providing important context such as threat details and the path a vulnerability takes through a program. And, it’s integrated with [GitLab Duo Enterprise AI](https://about.gitlab.com/gitlab-duo/) to help developers understand and resolve vulnerabilities faster. AppSec teams can also scale their expertise by integrating third-party security training right into the GitLab platform. \n\n**Security built into developer workflows**\n* *Integrated* into the SDLC is not the same as *built* into the SDLC. Advanced SAST is a native component of our platform, ensuring security is incorporated within existing developer workflows. With a unified solution to manage the entire SDLC, developers can identify, prioritize, and remediate vulnerabilities without disrupting their flow.\n\nHere is an example of the findings of an Advanced SAST scan: \n\n![Advanced SAST - code flow](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675850/Blog/Content%20Images/code-flow_dark-mode__1_.png)\n\n## What to know about the Advanced SAST rollout\nIf you’re already using GitLab SAST, we want to ensure you have the chance to coordinate the rollout of Advanced SAST.\n\nHere are key points:\n* Advanced SAST scanning is available in GitLab 17.3 or newer, but it’s disabled by default so you can choose when to make the switch. You can [enable Advanced SAST](https://docs.gitlab.com/ee/user/application_security/sast/gitlab_advanced_sast.html#configuration) for [the languages it supports](https://docs.gitlab.com/ee/user/application_security/sast/gitlab_advanced_sast.html#supported-languages) across projects, groups, or your entire instance.\n* GitLab 17.4 includes helpful features that make it easier to switch to Advanced SAST, including a new [vulnerability code flow view](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/#vulnerability-code-flow) and automatic translation from existing vulnerability records.\n* We plan to enable Advanced SAST by default in a future release, no later than GitLab 18.0. We’ll announce the final timeline and details soon.\n\nFor the latest updates on how to upgrade to Advanced SAST, check the [Advanced SAST documentation](https://docs.gitlab.com/ee/user/application_security/sast/gitlab_advanced_sast.html). We also have a walkthrough in the video below:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/xDa1MHOcyn8?si=2zVY_rRSu1wpHP__\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## What’s next for SAST  \nLooking ahead, we’re already working on [new features and improvements](https://about.gitlab.com/direction/secure/static-analysis/sast/) to help teams write more secure software together, faster. We’re particularly focused on:\n\n* **Upgrading more languages to Advanced SAST**, like PHP, Ruby, C, and C++, so more teams can benefit from more accurate vulnerability findings and cross-file, cross-function scanning.\n* **Real-time SAST scanning in the IDE**, so developers can write more secure code as they’re programming – before they even commit or push.\n* **Incremental scanning**, analyzing only modified code so developers can quickly identify vulnerabilities without waiting on full-repository scans. \n\n> If you’re an existing GitLab Ultimate customer and would like to learn more about how Advanced SAST can help improve your application security program, visit our [Advanced SAST documentation](https://docs.gitlab.com/ee/user/application_security/sast/gitlab_advanced_sast.html) where we cover implementation requirements, use cases, and more.  \n\n***Disclaimer:** This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab.*\n",[694,994,719,9,848],{"slug":1716,"featured":91,"template":698},"gitlab-advanced-sast-is-now-generally-available","content:en-us:blog:gitlab-advanced-sast-is-now-generally-available.yml","Gitlab Advanced Sast Is Now Generally Available","en-us/blog/gitlab-advanced-sast-is-now-generally-available.yml","en-us/blog/gitlab-advanced-sast-is-now-generally-available",{"_path":1722,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1723,"content":1729,"config":1735,"_id":1737,"_type":14,"title":1738,"_source":16,"_file":1739,"_stem":1740,"_extension":19},"/en-us/blog/gitlab-ai-assisted-features",{"title":1724,"description":1725,"ogTitle":1724,"ogDescription":1725,"noIndex":6,"ogImage":1726,"ogUrl":1727,"ogSiteName":686,"ogType":687,"canonicalUrls":1727,"schema":1728},"GitLab details AI-assisted features in the DevSecOps platform","In a fireside chat, CEO and co-founder Sid Sijbrandij shared demos of AI-assisted features available today in gitlab.com.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749669077/Blog/Hero%20Images/ai-fireside-chat.png","https://about.gitlab.com/blog/gitlab-ai-assisted-features","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab details AI-assisted features in the DevSecOps platform\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sid Sijbrandij\"}],\n        \"datePublished\": \"2023-05-03\",\n      }",{"title":1724,"description":1725,"authors":1730,"heroImage":1726,"date":1732,"body":1733,"category":781,"tags":1734},[1731],"Sid Sijbrandij","2023-05-03","\nThis morning, GitLab’s Chief Financial Officer Brian Robins and I led a fireside chat focused on [GitLab’s AI strategy](https://ir.gitlab.com/news-releases/news-release-details/gitlab-hold-ai-fireside-chat-sid-sijbrandij), AI’s role in solving customer pain points, and our AI product roadmap.\n\nAI marks a big industry shift that will make it easier to develop, secure, and operate software. We plan to infuse AI throughout the software development lifecycle by incorporating it into our comprehensive enterprise DevSecOps platform.\n\nWe will lead with a customer-centric approach focused on privacy first, where customers know their intellectual property is secured. One way we are accomplishing this is with [our recently announced generative AI partnership with Google](https://about.gitlab.com/press/releases/2023-05-02-gitLab-and-google-cloud-partner-to-expand-ai-assisted-capabilities.html). This will allow GitLab to use Google's generative AI foundation models to provide customers with AI-powered offerings within our cloud infrastructure. We’ll maintain our commitment to protecting user privacy by containing customer intellectual property and source code within GitLab's cloud infrastructure.\n\nWatch the AI fireside chat:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/ejWeMdVz8Nk\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen>\u003C/iframe>\n\n\u003C/figure>\n\u003C!-- blank line -->\n\nDuring the fireside chat, we introduced AI-assisted features available to GitLab customers today on gitlab.com. We provided a live demo of these capabilities that can be utilized by everyone throughout the software development lifecycle. \n\n![List of AI-assisted capabilities](https://about.gitlab.com/images/blogimages/ai-assisted-capabilities-detailed.png){: .shadow}\n\nWe also discussed how these capabilities are focused on three personas: development, security and operations teams, and have features available for all users. Watch the demos for these capabilities available on gitlab.com today:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe width=\"560\" height=\"315\" src=\"https://www.youtube-nocookie.com/embed/ILJeqWoVswM\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen>\u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## AI for Developer Teams \n\n### Code Suggestions\n- Enables developers to write code more efficiently by viewing code suggestions as they type. \nLearn more about [Code Suggestions](/blog/ai-assisted-code-suggestions/).\n\n### Suggested Reviewers\n- Helps customers receive faster and higher quality reviews by automatically finding the right people to review a merge request.\nLearn more about [Suggested Reviewers](https://docs.gitlab.com/ee/user/project/merge_requests/reviews/data_usage.html).\n\n### Summarize MR Changes\n- Helps merge request authors to drive alignment and action by efficiently communicating the impact of their changes.\nLearn more about [Summarize MR Changes](/blog/merge-request-changes-summary-ai/).\n\n### Summarize My MR Review\n- Enables better handoffs between authors and reviewers and helps reviewers efficiently understand many merge request suggestions. \nLearn more about [Summarize My MR Review](/blog/summarize-my-merge-request-review/).\n\n## AI for Security and Operations\n\n### Explain This Vulnerability\n- Helps developers remediate vulnerabilities more efficiently and uplevel their skills, enabling them to write more secure code.\nLearn more about [Explain This Vulnerability](/blog/explain-this-vulnerability/).\n\n### Generate Tests in MRs\n- Automates repetitive tasks for developers and helps them catch bugs early.\nLearn more about [Generate Tests in MRs](/blog/merge-request-suggest-a-test/).\n\n### Explain This Code\n- Allows DevSecOps teams to get up to speed quickly on code.\nLearn more about [Explain This Code](/blog/explain-this-code/).\n\n## AI for everyone\n\n### Issue Comment Summaries\n- Quickly gets everyone up to speed on lengthy conversations to ensure they are all on the same page.\nLearn more about [Issue Comment Summaries](/blog/summarize-issues/).\n\n### GitLab Chat\n- Helps quickly identify useful information in large volumes like documentation.\nLearn more about [GitLab Chat](https://gitlab.com/groups/gitlab-org/-/epics/10220).\n\n### Value Stream Forecasting\n- Predicts productivity metrics and identifies anomalies across your software development lifecycle.\nLearn more about [Value Stream Analytics](https://docs.gitlab.com/ee/user/group/value_stream_analytics/).\n\nThese are just the beginning of many features we have in the works leveraging generative AI to provide our customers [AI-assisted features](/topics/devops/the-role-of-ai-in-devops/) across our DevSecOps platform. With our value of iteration at the heart of our work, we are actively improving all the capabilities we announced today as well as introducing new capabilities. [AI is in all we do](/company/yearlies/#fy24-yearlies) and we intend to ship many capabilities throughout the year as they become ready.  \n\n> Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Watch today!](https://about.gitlab.com/seventeen/)",[994,719,717,9],{"slug":1736,"featured":6,"template":698},"gitlab-ai-assisted-features","content:en-us:blog:gitlab-ai-assisted-features.yml","Gitlab Ai Assisted Features","en-us/blog/gitlab-ai-assisted-features.yml","en-us/blog/gitlab-ai-assisted-features",{"_path":1742,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1743,"config":1746,"content":1748,"_id":1755,"_type":14,"title":1756,"_source":16,"_file":1757,"_stem":1758,"_extension":19},"/en-us/blog/gitlab-and-accenture-announce-global-reseller-agreement",{"noIndex":6,"title":1744,"description":1745},"GitLab and Accenture announce Global Reseller Agreement","New reseller agreement empowers Accenture to offer GitLab's comprehensive DevSecOps platform.",{"featured":6,"template":698,"slug":1747},"gitlab-and-accenture-announce-global-reseller-agreement",{"title":1744,"description":1745,"category":994,"tags":1749,"authors":1750,"heroImage":1752,"date":1753,"body":1754},[994,848,9],[1751],"GitLab","https://res.cloudinary.com/about-gitlab-com/image/upload/v1751568278/bots3gyfarx8qysbkw6c.png","2025-09-15","We're excited to announce that GitLab and Accenture have signed a global reseller agreement, establishing Accenture as an authorized GitLab reseller and Professional Services Provider. This agreement enables Accenture to provide GitLab's complete DevSecOps platform directly to customers through multiple fulfillment channels, including the AWS Marketplace.\n\n## A milestone in collaboration\n\nThis collaboration combines GitLab's comprehensive, intelligent DevSecOps platform with Accenture's extensive expertise in digital transformation and implementation services, enabling organizations to build and deliver secure software at scale. The global reseller agreement provides a global framework that can be easily adapted to local conditions.\n\nThe collaboration will initially focus on several key areas:\n\n1. **Enterprise-scale DevSecOps Transformation:** Helping organizations modernize their development practices and streamline their software delivery lifecycle  \n2. **Mainframe Modernization:** Assisting customers with migrating from legacy systems  \n3. **GitLab Duo with Amazon Q:** Offering AI-driven software development to organizations looking to accelerate development velocity while maintaining end-to-end security and compliance\n\n## Looking ahead\n\nWe’re looking forward to helping our joint customers accelerate innovation, streamline development processes, and strengthen their security posture to achieve their business objectives more effectively.\n\nFor more information about how GitLab and Accenture can help your organization, please [visit our partner site](https://about.gitlab.com/partners/channel-partners/#/2328213) or contact your Accenture or GitLab representative.","content:en-us:blog:gitlab-and-accenture-announce-global-reseller-agreement.yml","Gitlab And Accenture Announce Global Reseller Agreement","en-us/blog/gitlab-and-accenture-announce-global-reseller-agreement.yml","en-us/blog/gitlab-and-accenture-announce-global-reseller-agreement",{"_path":1760,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1761,"content":1767,"config":1773,"_id":1775,"_type":14,"title":1776,"_source":16,"_file":1777,"_stem":1778,"_extension":19},"/en-us/blog/gitlab-and-google-together-at-google-cloud-next-23",{"title":1762,"description":1763,"ogTitle":1762,"ogDescription":1763,"noIndex":6,"ogImage":1764,"ogUrl":1765,"ogSiteName":686,"ogType":687,"canonicalUrls":1765,"schema":1766},"GitLab and Google together at Google Cloud Next '23","Here's a roundup of all the GitLab events and announcements at the Next ‘23 conference.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679290/Blog/Hero%20Images/gitlabgooglecloud.png","https://about.gitlab.com/blog/gitlab-and-google-together-at-google-cloud-next-23","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab and Google together at Google Cloud Next '23\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Nima Badiey\"}],\n        \"datePublished\": \"2023-08-22\",\n      }",{"title":1762,"description":1763,"authors":1768,"heroImage":1764,"date":1770,"body":1771,"category":994,"tags":1772},[1769],"Nima Badiey","2023-08-22","\nAfter a pandemic-related hiatus from in-person events, we’re excited that Google Cloud Next ‘23 is back in person Aug. 29 - 31 at the Moscone Center in San Francisco – and GitLab will be there. Next ’23  promises to be a packed event, with exciting announcements and new product introductions from Google and its partners. \n\nIf you’re going to Next ‘23, here’s a quick summary of where to find GitLab at the event, including speaking sessions, our booth in the expo hall, and our storefront, to learn more about the [most comprehensive AI-powered DevSecOps Platform](https://about.gitlab.com). And don’t forget to check out the [GitLab at Next '23 event page](https://about.gitlab.com/events/) for updates and invites!\n\n### All week\nJoin us at our booth #633 on the expo floor to meet the GitLab team and learn how GitLab and Google Cloud are partnering to deliver secure, enterprise-grade AI. Talk to DevSecOps experts, dive into our new AI capabilities built directly into the platform, and learn best practices you can apply to your own environment. Get all your technical questions answered, and let us know what features you'd like to see in the GitLab platform!\n* We also have a Pop-Up Meeting Experience at the 4th Street Entrance to the [Metreon](https://www.shoppingmetreon.com/). Our team is providing demos and Q&A for [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our suite of AI-powered capabilities that can enhance your workflows throughout the software development lifecycle. Register for a coffee chat in our exclusive gathering space to start your day off right!\n* GitLab team members are available all week to meet customers, partners, and fellow Google sellers, so be sure to ask your GitLab sales representatives who and how to connect with them in person.\n\n### Tuesday, Aug. 29\n* If you’re attending the Executive Women’s Network breakfast, be sure to say hi to our Patty Cheung, Vice President of Sales for Channel and Alliances. Patty recently joined the GitLab team and is focusing her team on helping customers leverage GitLab’s extensive partner ecosystem to adopt, scale, and grow their businesses on GitLab’s AI-powered DevSecOps Platform.\n* Grab a seat early and as close to the stage as you can because you don’t want to miss out on Google Cloud CEO Thomas Kurian’s opening keynote. You’ll learn how GitLab is building our latest AI-assisted services, such as Explain this Vulnerability and Code Suggestions on Google’s PaLM2-based VertexAI and Codey upgrades.\n* Join us on August 29th at 6:30 p.m. for a Happy Hour at the GitLab storefront at the Metreon before the rest of the evening’s festivities. Don’t forget to [grab an invite](https://page.gitlab.com/20230829-google-cloud-next-meetings-happy-hour.html) before you come.\n\n### Wednesday, Aug. 30\n* Make sure to [register for our Aug. 30th breakfast](https://page.gitlab.com/event_august30_googlenextexecbreakfast_sanfrancisco.html?utm_medium=corpmktg&utm_source=marketo&utm_campaign=googlenextbreakfast20230830&utm_content=ownedevent&utm_budget=fmm) from 8:30-10AM at the GitLab Storefront in the Metreon with lightning talks on key AI initiatives!\n* GitLab’s Chief Product Officer David DeSanto will join Google’s June Yang, vice president of Cloud AI and Industry Solutions, at the first spotlight session (SPTL200)  “[What's new with generative AI at Google Cloud](https://cloud.withgoogle.com/next/session-library?session=SPTL200#partner-summit)” at 1:30 p.m. to share how GitLab has been able to accelerate our AI-based product features by leveraging Google’s Vertex and Codey frameworks.\n* After the session, David will join Google’s Gabe Monroy, vice president of Developer Experience, at the Application Developers spotlight (SPTL201) “[What's next for application developers](https://cloud.withgoogle.com/next/session-library?session=SPTL201#partner-summit)” at 4:45 p.m. They will share some exciting updates on how Google and GitLab are expanding their partnership.\n\n### Thursday, Aug. 31\n* We’ll get more hands on with two panel sessions where audience members will hear from GitLab and Google product leads and get a chance to ask questions and interact with the teams.\n* Starting at 9:00 a.m., Mike Flouton, GitLab vice president of Product, will join Google’s Parashar Shah, product manager for Vertex AI and Codey APIs, on a panel at the (ai-ml208) “[Accelerate software development with Vertex AI’s Codey APIs](https://cloud.withgoogle.com/next/session-library?session=ai-ml208#partner-summit)” session. They will discuss how GitLab uses Google’s many AI tools and frameworks to build Explain this Vulnerability and Code Suggestions on Google’s PaLM2-based VertexAI and Codey upgrades, just a small example of the 15+ new AI-assisted features we have planned. \n* At 10:15 a.m., join Hillary Benson, senior director of Product at GitLab, for a panel with Google team members, including Stephanie Wong, product manager for Google Cloud’s Duet AI. As part of the continuing series on all things AI, the (ai-ml214) “[Prompt engineering: Getting the skill your team needs next](https://cloud.withgoogle.com/next/session-library?session=ai-ml214#partner-summit)” session will discuss how prompt engineering can impact knowledge workers' success in delivering improved productivity and better outcomes.\n\nIf you’re a GitLab partner, drop me a line via LinkedIn and let’s connect in person at Next ‘23!\n",[994,694,1040,9],{"slug":1774,"featured":6,"template":698},"gitlab-and-google-together-at-google-cloud-next-23","content:en-us:blog:gitlab-and-google-together-at-google-cloud-next-23.yml","Gitlab And Google Together At Google Cloud Next 23","en-us/blog/gitlab-and-google-together-at-google-cloud-next-23.yml","en-us/blog/gitlab-and-google-together-at-google-cloud-next-23",{"_path":1780,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1781,"content":1787,"config":1793,"_id":1795,"_type":14,"title":1796,"_source":16,"_file":1797,"_stem":1798,"_extension":19},"/en-us/blog/gitlab-at-aws-re-invent-2023",{"title":1782,"description":1783,"ogTitle":1782,"ogDescription":1783,"noIndex":6,"ogImage":1784,"ogUrl":1785,"ogSiteName":686,"ogType":687,"canonicalUrls":1785,"schema":1786},"GitLab at AWS re:Invent 2023","GitLab and AWS have streamlined development and security for DevSecOps teams. Learn how in lightning talks, sessions, live demos, and more.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664472/Blog/Hero%20Images/gitlabflatlogomap.png","https://about.gitlab.com/blog/gitlab-at-aws-re-invent-2023","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab at AWS re:Invent 2023\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Darwin Sanoy\"}],\n        \"datePublished\": \"2023-11-22\",\n      }",{"title":1782,"description":1783,"authors":1788,"heroImage":1784,"date":1790,"body":1791,"category":10,"tags":1792},[1789],"Darwin Sanoy","2023-11-22","GitLab will be at AWS re:Invent 2023 in Las Vegas, November 27 to December 1, to demonstrate how the GitLab DevSecOps Platform on Amazon Web Services delivers secure, enterprise-grade AI throughout the software development lifecycle. Stop by Booth #1152 in the Security Zone for [lightning talks, live demos, customer sessions, and more](https://about.gitlab.com/events/aws-reinvent/) all week. \n\nMake sure to [check out our event page and calendar](https://about.gitlab.com/events/aws-reinvent/) to find sessions, locations, opportunities to meet with GitLab, and more (note, they do not appear in the AWS event app). Some sessions will also be available on-demand after the conference.\n\nHere are some of the lightning talks GitLab will be presenting:\n\n**Frictionless developer experience: Using human habits to accelerate DevSecOps maturity and increase joy**\n\nGitLab’s long-standing approach to building DevSecOps pipelines aligns with AWS’ new emphasis on frictionless developer experiences. Join this session to learn how the GitLab DevSecOps platform represents a true “shift left” by empowering and streamlining developers’ normal workflow.\n\n[Add to calendar - Nov. 30](https://content.gitlab.com/viewer/65412018ca9e0b9d4b50acb2?iid=654966e4f2269af78f005ba1)\n\n**New integrations and solutions for using GitLab and AWS together**\n\nIn recent months, AWS and GitLab have built new service integrations for source control, CI, and CD. You'll learn how GitLab integrates with AWS CodeStar Connections, Amazon CodeGuru, OpenID, and more, as well as development and deployment solutions for Serverless.com Framework and Terraform to AWS.\n\nAdd to calendar\n* [Nov. 28](https://content.gitlab.com/viewer/65412018ca9e0b9d4b50acb2?iid=654144eef011a50313dc7113)\n* [Nov. 29](https://content.gitlab.com/viewer/65412018ca9e0b9d4b50acb2?iid=654942dfef8fa23b213f0eca)\n* [Nov. 30](https://content.gitlab.com/viewer/65412018ca9e0b9d4b50acb2?iid=65494b66a0b8daf9ca33a386)\n\n**Secure and assured Terraform development using GitLab security scanning policies and managed DevOps environments**\n\nThis lightning talk discusses and demonstrates working example code that extends GitLab's existing support for Terraform State management with full lifecycle-managed DevOps environments for merge requests, long-lived pre-production environments, production environments, and one-off experimental environments. Whether you are developing infrastructure as code specifically or embedding it with application code for the sake of easy environment support, this lightning talk has something to offer you.\n\n[Add to calendar - Nov. 28](https://content.gitlab.com/viewer/65412018ca9e0b9d4b50acb2?iid=654961043165b6f013635639)\n\n**Secure GitLab CD pipelines to AWS with OpenID Federation, OIDC, and JWT**\n\nGitLab has three ways to authenticate and authorize your CI and CD workloads into AWS environments. Adding and refining OpenID provides the ability to use an industry standard, which is the most advanced of the three. Join us to learn how to accomplish this highly secure integration option.\n\n[Add to calendar - Nov. 29](https://content.gitlab.com/viewer/65412018ca9e0b9d4b50acb2?iid=6549580763edc0caa46ea061)\n\n**Security intelligence through full integration of Amazon CodeGuru Security into GitLab**\n\nAWS CodeGuru Security has created a full integration that enables you to view scanner results in GitLab merge requests and security dashboards so you can use them to block merges in security policy merge approval rules — just like GitLab’s integrated security scanning results. Attend this lightning talk to learn more.\n\n[Add to calendar - Nov. 28](https://content.gitlab.com/viewer/65412018ca9e0b9d4b50acb2?iid=654953f963edc0cdbf6e8c6f)\n\n## GitLab and AWS: The year in review\nThroughout 2023, GitLab and AWS announced partner designations and new service integrations that enable development, security, and operations teams to collaborate more easily, to take advantage of AI at all stages, and to flexibly scale infrastructure to create and deploy secure software faster. \n\n#### AWS recognized GitLab as a partner in several categories\n\n- **AWS DevSecOps Partner Competency Specialty:** This specialty denotes that GitLab makes it easy for customers to [integrate security across every stage](https://about.gitlab.com/blog/aws-devsecops-competency-partner/) of the development and delivery cycles, providing rapid and contextual feedback to development, security, and ops teams.\n\n-  **Amazon Linux 2023 Ready Partner:** Amazon Linux 2023-specific RPM packages are available for GitLab, starting at [Version 16.3.0](https://docs.gitlab.com/ee/administration/package_information/supported_os.html) and for GitLab Runner. Official GitLab support for Amazon Linux 2023 also means GitLab builds the RPM packages and hosts them on our packages infrastructure, Graviton (arm64) and amd64 architectures are both supported. To install GitLab on Amazon Linux 2023, [follow these instructions](https://about.gitlab.com/install/#amazonlinux-2023). \n\nLearn more about [GitLab's AWS partner designations](https://docs.gitlab.com/ee/solutions/cloud/aws/gitlab_aws_partner_designations.html).\n\n#### AWS CodeStar Connections opens up a host of AWS service integrations\n\nAWS recently completed the integration of GitLab.com SaaS into its AWS CodeStar Connections service. This service is a foundational, shared service used by many other AWS services to connect to Git repositories outside of AWS. As a result, GitLab was immediately available to AWS services once this integration was completed.\n\nGitLab is available at CodeStar Connections throughout many AWS services for connectivity to Git. In addition, using a CodeStar Connection for an AWS CodePipeline opens up other service integrations that primarily rely on CodePipeline as their key integration point.\n\nHere is a visual map of the integrations that are currently available:\n\n![CodeStar Connections integrations](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749676883/Blog/Content%20Images/gitlabcodestarconnectionsintegration.png)\n\n#### AI customization with AWS CodeWhisperer\n[AWS CodeWhisperer's customization capability](https://aws.amazon.com/blogs/aws/new-customization-capability-in-amazon-codewhisperer-generates-even-better-suggestions-preview/) leverages CodeSuite Connections, allowing generative code suggestions to take into account the libraries and design patterns of your current application when suggesting new code. It does so with no ingestion of your code into the general LMM creation. AWS CodeWhisperer can be pointed to a GitLab repository. \n\n#### AWS CodeGuru and GitLab Ultimate secure scanning integration\nThe AWS CodeGuru team [built an integration with GitLab CI](https://docs.gitlab.com/ee/solutions/cloud/aws/gitlab_aws_integration.html#scm-integrations) as part of their build secure scanning capabilities. [Amazon CodeGuru Security findings](https://docs.aws.amazon.com/codeguru/latest/security-ug/get-started-gitlab.html) use GitLab’s vulnerability report formatting, enabling exports to integrate directly into GitLab Ultimate security features such as merge request views, security dashboards, and in-context remediation solutions and training. Importantly, it allows these findings to be addressed by GitLab Security Policy Merge Approval Rules. \n\n#### GitLab's new single-tenant Saas option sits atop AWS\nEarlier this year, GitLab launched [GitLab Dedicated](https://docs.gitlab.com/ee/subscriptions/gitlab_dedicated/), a single-tenancy solution for organizations in highly regulated industries that have complex regulatory, compliance, and data residency requirements. The fully isolated SaaS offering is hosted and managed by GitLab and deployed on AWS in a cloud region of the customer's choosing. [Learn more about how GitLab built GitLab Dedicated](https://about.gitlab.com/blog/building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated/).\n\n## Plan your week at AWS re:Invent\nFill your calendar with GitLab at AWS re:Invent! [Check out our calendar](https://about.gitlab.com/events/aws-reinvent/) of sponsored sessions, lightning talks, live demos, and more throughout the week at Booth #1152.\n",[1084,9,496,284],{"slug":1794,"featured":91,"template":698},"gitlab-at-aws-re-invent-2023","content:en-us:blog:gitlab-at-aws-re-invent-2023.yml","Gitlab At Aws Re Invent 2023","en-us/blog/gitlab-at-aws-re-invent-2023.yml","en-us/blog/gitlab-at-aws-re-invent-2023",{"_path":1800,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1801,"content":1806,"config":1812,"_id":1814,"_type":14,"title":1815,"_source":16,"_file":1816,"_stem":1817,"_extension":19},"/en-us/blog/gitlab-chat-ai",{"title":1802,"description":1803,"ogTitle":1802,"ogDescription":1803,"noIndex":6,"ogImage":839,"ogUrl":1804,"ogSiteName":686,"ogType":687,"canonicalUrls":1804,"schema":1805},"ML experiment: Use a chatbot to answer how-to questions","Learn how GitLab is experimenting with a docs chatbot that you can ask product questions in this latest installment of our ongoing 'AI/ML in DevSecOps' series.","https://about.gitlab.com/blog/gitlab-chat-ai","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"ML experiment: Use a chatbot to answer how-to questions\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sarah Waldner\"}],\n        \"datePublished\": \"2023-05-04\",\n      }",{"title":1802,"description":1803,"authors":1807,"heroImage":839,"date":1809,"body":1810,"category":781,"tags":1811},[1808],"Sarah Waldner","2023-05-04","\n\n\u003Ci>This blog post is part of an ongoing series about GitLab's journey to [build and integrate AI/ML into our DevSecOps platform](/blog/ai-ml-in-devsecops-series/). The series starts here: [What the ML is up with DevSecOps and AI?](/blog/what-the-ml-ai/). Throughout the series, we'll feature blogs from our product, engineering, and UX teams to showcase how we're infusing AI/ML into GitLab.\u003C/i>\n\nAt GitLab, [everyone can contribute](/company/mission/). As a platform, GitLab offers a wide variety of features, but it is hard to know everything GitLab is capable of without diligently combing through our documentation, testing out our features, or talking to someone at GitLab who can answer your questions. Reading documentation can send users down a rabbit hole and they may not get their question answered. This can lead to time spent with support, meetings with the Customer Success team, going back and forth with a solutions architect, coordinating with technical account managers, and maybe opting for some professional services hours. What if users had access to all the knowledge they needed at their fingertips 24/7 and could get their complex questions answered immediately?\n        \nIn an experimental feature, the [Global Search team](/handbook/engineering/development/enablement/data_stores/search/) used AI to create a chatbot that answers how-to questions about the GitLab product. It will respond with an explanation and relevant links to our documentation.   \n\n![GitLab Chat answering a simple question](https://about.gitlab.com/images/blogimages/gitlab_chat.gif){: .shadow}\n\nGetting answers on how-to questions while in the product eliminates time lost to context switching. The chat interface overlays the GitLab UI, which enables you to interface with a virtual expert alongside your work. This is especially helpful when you are involved in a complex multi-step task like setting up a gitlab-ci.yml file, configuring security policies, or editing a CODEOWNERS file.\n\nGitLab chat will answer any question that you would utilize our product documentation to answer. It also provides helpful links if the bot's response is not as detailed as you needed - the full documentation is just one click away.\n\n## Be part of our AI-assisted features journey\n\nThis experiment is just the start of the ways we're looking to infuse GitLab with AI/ML capabilities to help GitLab users become more efficient and effective at their jobs. We are [looking across the software development lifecycle](/blog/what-the-ml-ai/) for painful and time-consuming tasks that are ideal for AI Assisted features. We'll continue to share these demos throughout this blog series.\n\nInterested in using these AI-generated features? [Join our waitlist](https://forms.gle/9eeUkPJauKsbLaoz5) and share your ideas.\n\nContinue reading our ongoing series, \"[AI/ML in DevSecOps](/blog/ai-ml-in-devsecops-series/)\".\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[9,848,719,717],{"slug":1813,"featured":6,"template":698},"gitlab-chat-ai","content:en-us:blog:gitlab-chat-ai.yml","Gitlab Chat Ai","en-us/blog/gitlab-chat-ai.yml","en-us/blog/gitlab-chat-ai",{"_path":1819,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1820,"content":1823,"config":1830,"_id":1832,"_type":14,"title":1833,"_source":16,"_file":1834,"_stem":1835,"_extension":19},"/en-us/blog/gitlab-duo-agent-platform-what-is-next-for-intelligent-devsecops",{"noIndex":6,"title":1821,"description":1822},"GitLab Duo Agent Platform: What’s next for intelligent DevSecOps","GitLab Duo Agent Platform, a DevSecOps orchestration platform for humans and AI agents, leverages agentic AI for collaboration across the software development lifecycle.",{"heroImage":1824,"title":1821,"description":1822,"authors":1825,"date":1827,"body":1828,"category":781,"tags":1829},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1750687578/esmflevxk5bf3eezjhwk.png",[1826],"Bill Staples","2025-06-24","I’m thrilled to introduce the next evolution of Duo Workflow: GitLab Duo Agent Platform. This innovative platform extends agentic capabilities across the software development lifecycle, enabling teams to work in parallel with multiple AI agents.\n\nImagine starting your day like this:\n\n* You assign one AI agent to conduct deep research on an epic your team is working on, provide the latest updates on all contributions from the past week, and suggest a release post based on recent feature additions.\n* In parallel, you delegate a handful of accessibility bugs to several agents for analysis and to make the necessary code changes to resolve them.\n* Meanwhile, you ask another agent to review your complicated code changes and provide feedback before sending them to your teammate for formal review.\n* Finally, when the security team pings you about a new vulnerability that needs investigation across your entire project, you hand that research task to your security agent.\n\nAll of this happens simultaneously, while you focus on architecture decisions, creative problem-solving, and strategic technical work. GitLab Duo Agent Platform will let you delegate tasks to five, 10, or even 100 specialized agents — all with full context of your project, not just your code, including CI job logs, planning work items, and so much more. You’re automating the tedious work you have to do, so you can focus on the work that inspires you.\n\n**This isn't about replacing developers. It's about amplifying human creativity and expertise by removing the friction from routine tasks.** That’s the future we’re building with GitLab Duo Agent Platform.\n\n## What is GitLab Duo Agent Platform?\n\nGitLab Duo Agent Platform will enable many-to-many collaboration between engineers and [AI agents](https://about.gitlab.com/topics/agentic-ai/) across the full software development lifecycle, designed to help teams dramatically improve productivity and cycle time.\n\nBuilt on GitLab’s secure foundation, GitLab Duo Agent Platform is customizable and extendable. It empowers developers to build agents to tackle all kinds of software engineering problems, leveraging context across your entire software development lifecycle.\n\nGitLab Duo Agent Platform will go beyond code creation with specialized agents and custom workflows that can help with a nearly unlimited list of activities, including:\n\n* Issue implementation\n* Large-scale migrations/dependency upgrades\n* Automated documentation building/release posts\n* Fixing broken pipelines\n* Incident research support\n* Deep research of status and information on topics\n* Backlog administration\n* Vulnerability resolution\n* Reviews for specific types of code (e.g. database)\n* Quick internal tool building based on existing build blocks\n* and many more!\n\nYou will be able to use our agents out of the box as well as customize and extend them. We’re currently beta testing GitLab Duo Agent Platform with dozens of customers and will open beta access to more teams soon.\n\nWatch GitLab Duo Agent Platform in action:\n\u003Cdiv style=\"padding:56.25% 0 0 0;position:relative;\">\u003Ciframe src=\"https://player.vimeo.com/video/1095679084?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" title=\"Agent Platform Demo Clip\">\u003C/iframe>\u003C/div>\u003Cscript src=\"https://player.vimeo.com/api/player.js\">\u003C/script>\n\n## Choose your tools, your models, and your agents\n\nConsistent with GitLab’s commitment to being an open platform, GitLab agents will seamlessly interoperate with your choice of code-authoring developer tools via standard model context protocol (MCP) and the agent-to-agent (A2A) framework, whether you’re using Cursor, Claude Code, Windsurf, OpenAI Codex, or others.\n\nThe platform will accept code contributions from any development tool in your stack, whether that code was written by a human developer or generated by an AI agent. This means your existing workflows and preferred tools will continue to work seamlessly as you integrate agent capabilities.\n\nGitLab Duo Agent Platform will work with any approved language model that [meets our selection criteria](https://about.gitlab.com/ai-transparency-center/#ai-continuity-plan). For organizations with strict security requirements, it will support approved self-hosted models running in completely air-gapped environments. Your infrastructure requirements and security policies won’t limit your ability to benefit from agentic development.\n\n## Context is everything, and your GitLab Duo agents have it\n\nThe difference between a helpful AI tool and a truly intelligent agent comes down to context. With GitLab Duo Agent Platform, agents don't work in isolation — they're deeply integrated into the platform where development work happens.\n\nEvery agent will automatically understand the full picture of your projects, including your open issues and their history, the merge requests that resolved them, the structure and rationale behind your code, your CI/CD pipeline configurations, security findings, compliance requirements, and the intricate relationships between all these components.\n\nJust like your human team members, agents have all the context to help you ship secure software faster. Instead of just answering questions about code, they will be able to provide insights about how a proposed change might affect your deployment pipeline or suggest security improvements based on your existing compliance rules. We believe that the more your team works within GitLab’s DevSecOps platform, the smarter your agents will become.\n\n## Stay in control while agents scale your team\n\nBuilding trust with AI agents isn't fundamentally different from building trust with new team members. You need to see their work, understand their approach, and gradually increase their responsibilities as they prove their competence.\n\nThat's the philosophy behind our agent approval workflow. Before any agent makes changes to your code or environment, it will present you with a clear plan: what it understands about the issue, the approach it will take, and the specific actions it wants to perform. You’ll then get the opportunity to review, approve, or redirect as needed. Over time, as agents consistently deliver quality work, you will be able to grant them greater autonomy for routine tasks while maintaining oversight for complex or critical work.\n\n## Built for community and customization\n\nGitLab has always thrived on community contributions, and this year marked a milestone with record-breaking customer contributions to our platform. Now we're extending that same collaborative energy to AI agents through our open framework approach.\n\nGitLab Duo Agent Platform isn't just about the agents we build — it's about empowering you and the broader community to create specialized agents that solve your unique engineering challenges. Whether you need an agent that understands your specific coding standards, integrates with your custom toolchain, or handles domain-specific tasks, the platform will give you the building blocks to make it happen.\n\nThis community-driven model creates a virtuous cycle that leverages the strength of the GitLab community through global sharing, similar to our [CI/CD Catalog](https://about.gitlab.com/blog/ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch/). Diverse real-world use cases drive innovation. Enterprise feedback ensures reliability and security. And shared solutions benefit everyone. It's the same collaborative approach that has made GitLab successful, now applied to the frontier of agentic development.\n\n## How to get started\n\nIf you've been experimenting with [GitLab Duo Agentic Chat](https://about.gitlab.com/blog/gitlab-duo-chat-gets-agentic-ai-makeover/), now included with every GitLab 18 Premium and Ultimate GitLab.com user license, you've already gotten a taste of what's possible with AI agents in your development workflow.\n\nTo see what GitLab Duo Agent Platform can do and what we’re working on, check out the [demos in the recording of our annual GitLab 18 release event](https://about.gitlab.com/eighteen/).\n\nWant to be among the first to experience it? Sign up for the GitLab [Duo Agent Platform beta waitlist](https://about.gitlab.com/gitlab-duo/agent-platform/). This summer, we'll be opening access to more teams, with new agent features coming out in GitLab 18's upcoming releases throughout the year. We expect general availability this winter.\n\n*Disclaimer: This presentation contains information related to upcoming products, features, and functionality. It is important to note that the information in this presentation is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this presentation and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab Inc.*\n\n## Learn more\n\n- [From vibe coding to agentic AI: A roadmap for technical leaders](https://about.gitlab.com/the-source/ai/from-vibe-coding-to-agentic-ai-a-roadmap-for-technical-leaders/)\n- [What is agentic AI?](https://about.gitlab.com/topics/agentic-ai/)\n- [DevOps automation and AI agents](https://about.gitlab.com/topics/agentic-ai/devops-automation-ai-agents/)\n- [AI-augmented software development: Agentic AI for DevOps](https://about.gitlab.com/topics/agentic-ai/ai-augmented-software-development/)\n- [AI-driven code analysis: The new frontier in code security](https://about.gitlab.com/topics/agentic-ai/ai-code-analysis/)",[717,9,994,848],{"featured":91,"template":698,"slug":1831},"gitlab-duo-agent-platform-what-is-next-for-intelligent-devsecops","content:en-us:blog:gitlab-duo-agent-platform-what-is-next-for-intelligent-devsecops.yml","Gitlab Duo Agent Platform What Is Next For Intelligent Devsecops","en-us/blog/gitlab-duo-agent-platform-what-is-next-for-intelligent-devsecops.yml","en-us/blog/gitlab-duo-agent-platform-what-is-next-for-intelligent-devsecops",{"_path":1837,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1838,"content":1844,"config":1849,"_id":1851,"_type":14,"title":1852,"_source":16,"_file":1853,"_stem":1854,"_extension":19},"/en-us/blog/gitlab-duo-chat-101-get-more-done-on-gitlab-with-our-ai-assistant",{"title":1839,"description":1840,"ogTitle":1839,"ogDescription":1840,"noIndex":6,"ogImage":1841,"ogUrl":1842,"ogSiteName":686,"ogType":687,"canonicalUrls":1842,"schema":1843},"GitLab Duo Chat 101: Get more done on GitLab with our AI assistant","In this first article in our series learn how Chat can improve developer productivity – for example, by summarizing issues – and how to improve prompts to get better answers faster.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099126/Blog/Hero%20Images/Blog/Hero%20Images/GitLab_Duo_Blog_Hero_1800x945_r2_B%20%281%29_6a2UB7TOQk3JKxyb5yqYtc_1750099126039.png","https://about.gitlab.com/blog/gitlab-duo-chat-101-get-more-done-on-gitlab-with-our-ai-assistant","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab Duo Chat 101: Get more done on GitLab with our AI assistant\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Abubakar Siddiq Ango\"}],\n        \"datePublished\": \"2024-05-29\",\n      }",{"title":1839,"description":1840,"authors":1845,"heroImage":1841,"date":1846,"body":1847,"category":781,"tags":1848},[1455],"2024-05-29","GitLab Duo Chat became [generally available](https://about.gitlab.com/blog/gitlab-duo-chat-now-generally-available/) in [GitLab 16.11](https://about.gitlab.com/releases/2024/04/18/gitlab-16-11-released/) and its power as a personal assistant can not be overstated. On a DevSecOps platform, more has to happen than just generating code; planning, discussions, security, compliance, and technical reviews are all critical to developing secure software faster. Issues, epics, merge requests, and other sections of GitLab are where this work happens, with knowledge often buried deep in comment threads. It can take a lot of time to get up to speed on these threads, especially when they've grown to hundreds of comments and interactions and when you've been away from them for a while. This is where GitLab Duo Chat can help.\n\nIn this first part of our GitLab Duo Chat 101 series, we'll introduce you to Chat's capabilities and then dig into how to use Chat to summarize comment threads.\n\n> Live demo! Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Register today](https://about.gitlab.com/seventeen/)!\n\n## GitLab Duo Chat's capabilities\n\nWith Chat, you can refactor [existing code](https://docs.gitlab.com/ee/user/gitlab_duo_chat.html#refactor-code-in-the-ide), learn how a [block of code works](https://docs.gitlab.com/ee/user/gitlab_duo_chat.html#explain-code-in-the-ide), and write [tests](https://docs.gitlab.com/ee/user/gitlab_duo_chat.html#write-tests-in-the-ide) for your code, learn about your issues and epics, and much more. Depending on your prompts, you can make Chat do impressive things that boost developer productivity. In the video below, I showcased how you can use GitLab Duo Chat to interact with GitLab and learn about your issues and epics.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/RJezT5_V6dI?si=XlXGs2DHAYa8Awzs\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Use cases   \n\nGitLab Duo Chat’s capabilities allow for productivity gains across multiple parts of the software development lifecycle:\n\n- Product and project managers can use Chat’s issues and epics capabilities to gain insights into discussions and plan faster.\n- Developers can create solutions faster with code suggestions and refactoring capabilities. When it comes to working with legacy code or code from other team members, less time is spent on research with the ` /explain` capability providing the necessary insights to understand the code.\n- Quality assurance and test engineers can generate tests and check for vulnerabilities\n- New employees can get a better understanding of their code base and get started solving problems.\n- Beginner programmers can understand and pick up a language or framework quickly and create solutions with Chat providing next steps and insights.\n\n> Check out \"[10 best practices for using GitLab Duo Chat](https://about.gitlab.com/blog/10-best-practices-for-using-ai-powered-gitlab-duo-chat/)\" for tips and tricks to craft AI prompts. \n\n## Summarizing issues\n\nWhen you encounter an issue, especially one with a lot of comments, you skim through the issue description, along with a couple of comments, but can't always get the complete picture of the conversations. GitLab Duo Chat can get you up to speed fast. In the image below, I asked Chat to summarize an issue along with a follow-up question. In two prompts, I got what I needed to understand what is going on in the issue without spending hours reading through the comments.\n\n![Chat summarizing an issue](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099137/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750099137154.png)\n\nYou can use GitLab Duo Chat on the GitLab interface, as well as [the WebIDE, Visual Studio Code, and JetBrains interfaces](https://docs.gitlab.com/ee/user/gitlab_duo_chat.html#use-gitlab-duo-chat-in-the-web-ide).\n\n## Prompts and context\n\nGetting the best responses from any AI tool requires carefully crafting the questions asked. Sometimes, you need to give examples of the responses you expect to prime the large language models (LLMs) toward a desired response. Here are some areas to focus on to get desired responses.\n\n### Context\n\nHere are three prompts with similar objectives but worded differently:\n\n| Prompt 1     | Prompt 2     | Prompt 3    |\n| ---------- | ---------- | ---------- |\n| ![Prompt: Can you summarize this issue's description?](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099137/Blog/Content%20Images/Blog/Content%20Images/image5_aHR0cHM6_1750099137154.png)       | ![Prompt: Can you provide a high-level summary of this issue?](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099137/Blog/Content%20Images/Blog/Content%20Images/image4_aHR0cHM6_1750099137155.png)      | ![Prompt: Why is this issue popular?](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099137/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750099137156.png)      |\n\nThe context, “this issue,” is common among the three prompts; this tells Chat what resource to use in looking for answers. Prompt 1 gives additional context on what to focus on: the description of the issue. Prompt 2 is not limited in its scope, which means the LLMs will spend more time going through the description and all the comments to provide a more detailed summary of the whole issue. (Note: As of the publication of this blog, there were more than 90 comments in that issue.) Prompt 3 got a poorer response because not much expectation was set for the type of response expected. \n\n[Low-context communication](https://handbook.gitlab.com/handbook/company/culture/all-remote/effective-communication/#understanding-low-context-communication) is critical in crafting your prompt for the best responses, as all information needed for the LLMs to provide an informed response is provided.\n\n### Simplicity\n\nThe wordiness of prompts can sometimes lead to incorrect or no responses. In the image below, you can see that rephrasing a prompt from “Customers have mentioned why this issue is important to them. Can you list the top 3 reasons they mentioned?” to “Why is this issue important to customers?” led to the expected response. When you don’t get the response you desire, simplifying or changing the words used in your prompt can improve the quality of responses.\n\n![Wordy Chat prompts](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099137/Blog/Content%20Images/Blog/Content%20Images/image6_aHR0cHM6_1750099137158.png)\n\n### Follow-up questions\n\nGitLab Duo Chat can have follow-up conversations – an essential capability. In the image below, I continued asking how the issue in question can be solved in GitLab's code along with a follow-up question asking for code samples.\n\n![Streamlined Chat prompt shown](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099137/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750099137158.png)\n\nFollow-up questions allow the application to maintain context and provide faster responses. A recommendation is to provide parts of Chat’s previous responses in the next prompt. In the example above, I mentioned “Rails App,” as previously suggested. \n\n## Get started with GitLab Duo Chat \n\nGitLab Duo Chat does more than help you write better code, it helps you navigate through problems and quickly find solutions. With the right prompts and context, you can build secure software faster.\n\n> Want to try GitLab Duo Chat? [Start your free trial](https://about.gitlab.com/gitlab-duo/#free-trial) today.",[717,496,9,827],{"slug":1850,"featured":91,"template":698},"gitlab-duo-chat-101-get-more-done-on-gitlab-with-our-ai-assistant","content:en-us:blog:gitlab-duo-chat-101-get-more-done-on-gitlab-with-our-ai-assistant.yml","Gitlab Duo Chat 101 Get More Done On Gitlab With Our Ai Assistant","en-us/blog/gitlab-duo-chat-101-get-more-done-on-gitlab-with-our-ai-assistant.yml","en-us/blog/gitlab-duo-chat-101-get-more-done-on-gitlab-with-our-ai-assistant",{"_path":1856,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1857,"content":1863,"config":1869,"_id":1871,"_type":14,"title":1872,"_source":16,"_file":1873,"_stem":1874,"_extension":19},"/en-us/blog/gitlab-duo-chat-beta",{"title":1858,"description":1859,"ogTitle":1858,"ogDescription":1859,"noIndex":6,"ogImage":1860,"ogUrl":1861,"ogSiteName":686,"ogType":687,"canonicalUrls":1861,"schema":1862},"Say hello to GitLab Duo Chat: A new level of AI-assisted productivity","Learn how GitLab Duo Chat, releasing Nov. 16 in Beta, can help elevate your coding skills, streamline onboarding, and supercharge team efficiency.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749669095/Blog/Hero%20Images/gitlabduo.png","https://about.gitlab.com/blog/gitlab-duo-chat-beta","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Say hello to GitLab Duo Chat: A new level of AI-assisted productivity\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Torsten Linz\"}],\n        \"datePublished\": \"2023-11-09\",\n      }",{"title":1858,"description":1859,"authors":1864,"heroImage":1860,"date":1866,"body":1867,"category":781,"tags":1868},[1865],"Torsten Linz","2023-11-09","\n[GitLab Duo Chat](https://docs.gitlab.com/ee/user/gitlab_duo_chat.html), the newest feature in the GitLab Duo suite of AI-assisted capabilities, helps teams write and understand code faster, get up to speed on the status of projects, and quickly learn GitLab. Chat will be available in Beta starting November 16.\n\nChat also will be included in our [Web IDE](https://docs.gitlab.com/ee/user/project/web_ide/) and [GitLab Workflow extension for VS Code](https://docs.gitlab.com/ee/editor_extensions/visual_studio_code/) as an experimental release. Get code explanations, generate tests, and create code right where your development work happens; no need for context switching. \n\nWe launched the [GitLab Duo suite](https://about.gitlab.com/gitlab-duo/) earlier this year to bolster software development teams' workflow, helping you deliver more secure software at an unprecedented pace and create more value for your customers. GitLab is the only platform that brings AI-powered planning tools, code creation, security scanning, and vulnerability remediation all into a single developer-friendly experience.\n\nChat will serve as the foundational technology driving our AI-powered GitLab Duo features, such as Vulnerability Summary and Root Cause Analysis. This will enable you to pose in-context follow-up questions for a more thorough investigation.\n\n> [Contact our sales team](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/) to get started with GitLab Duo Chat.\n\nIn our [Global DevSecOps Report: The State of AI in Software Development](https://about.gitlab.com/developer-survey/#ai), 83% of respondents said that implementing AI in their software development processes is essential to avoid falling behind, and they ranked chatbots among their top three AI use cases. Chat, which will be released for Ultimate tier customers as part of GitLab 16.6, is the perfect feature to help you maintain your competitive advantage. Here's why.\n\n## Designed to support everyone across the software development process \nFrom coding assistance to productivity tips, Chat provides real-time support for technical and non-technical users across the entire software development lifecycle. \n\n- **Inspiration on demand:** Need help determining the next best step in your workflow? Chat is ever-ready to ignite your ideation process.\n\n- **Elevate productivity:** Chat shoulders the burden of routine tasks so you can channel your energy into delivering value to your customers. \n\n- **Guidance at every step:** Whether you're a GitLab expert or a newcomer, Chat is your go-to coach, helping you become an expert in any process or feature.\n\nSometimes, there isn't enough time in the day, and even though you want to focus on important tasks, there are many little things you need to do. \n\n- **Code assistance:** Chat can assist in decoding the mysteries of unfamiliar code. It can explain,  propose tests, or simplify the code. You can also use Chat to write code from scratch interactively.\n\n![Chat in Web IDE](https://about.gitlab.com/images/blogimages/2023-11-09-chat-beta/chatbetaissueepicmanagement.gif){: .shadow}\n\n- **Issue and epic management:** Summarize an issue in seconds, turn comments into an issue description, or distill specific information from large epics easily. You can ask any question about the content of an epic or an issue. Plan work with issues and epics faster with the help of Chat. \n\n![Chat issue and epic management example](https://about.gitlab.com/images/blogimages/2023-11-09-chat-beta/chatinideexperimentalrelease.gif){: .shadow}\n\n- **Onboarding and learning made simple:** Whether you are onboarding to GitLab or you are already an expert learning how to use GitLab is streamlined with Chat.\n\n![Chat learning example](https://about.gitlab.com/images/blogimages/2023-11-09-chat-beta/chatbetareleaselearninglong.gif){: .shadow}\n\n## How your data stays your data  \nChat does not use your proprietary code or inputs to Chat as training data. This privacy-first approach includes both the prompt and the output of Chat. GitLab Duo uses the right large language models (LLMs) for each use case. For instance, Anthropic Claude-2 and Vertex AI Codey with text embedding-gecko LLMs power Chat. Our [publicly available documentation](https://docs.gitlab.com/ee/user/ai_features.html) describes all AI models GitLab Duo uses and [how it uses your data](https://docs.gitlab.com/ee/user/ai_features.html#data-privacy). \n\n## The road ahead for GitLab Duo  \t\nAs we continue to innovate and improve GitLab Duo, we're excited to share that our [Code Suggestions](https://about.gitlab.com/solutions/code-suggestions/) capability will transition from Beta to general availability later this year. We look forward to seeing the transformative impact GitLab Duo will have on your software development efforts. Learn more about GitLab Duo Chat in [our documentation](https://docs.gitlab.com/ee/user/gitlab_duo_chat.html) and [share your feedback and ideas](https://gitlab.com/gitlab-org/gitlab/-/issues/430124). \n\nTo get started with GitLab Duo Chat, please [contact our sales team](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/).\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[717,9,994],{"slug":1870,"featured":6,"template":698},"gitlab-duo-chat-beta","content:en-us:blog:gitlab-duo-chat-beta.yml","Gitlab Duo Chat Beta","en-us/blog/gitlab-duo-chat-beta.yml","en-us/blog/gitlab-duo-chat-beta",{"_path":1876,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1877,"content":1883,"config":1890,"_id":1892,"_type":14,"title":1893,"_source":16,"_file":1894,"_stem":1895,"_extension":19},"/en-us/blog/gitlab-duo-chat-get-to-know-productivity-boosting-ai-enhancements",{"title":1878,"description":1879,"ogTitle":1878,"ogDescription":1879,"noIndex":6,"ogImage":1880,"ogUrl":1881,"ogSiteName":686,"ogType":687,"canonicalUrls":1881,"schema":1882},"GitLab Duo Chat: Get to know productivity-boosting AI enhancements","Learn about Chat's new capabilities, including migration to Claude 3.5 Sonnet, new slash command helpers, and the integration of Root Cause Analysis and Explain Vulnerability features.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098629/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%281%29_77JeTV9gAmbXM0224acirV_1750098628882.png","https://about.gitlab.com/blog/gitlab-duo-chat-get-to-know-productivity-boosting-ai-enhancements","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab Duo Chat: Get to know productivity-boosting AI enhancements\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Jannik Lehmann\"},{\"@type\":\"Person\",\"name\":\"David O'Regan\"}],\n        \"datePublished\": \"2024-10-03\",\n      }",{"title":1878,"description":1879,"authors":1884,"heroImage":1880,"date":1887,"body":1888,"category":781,"tags":1889},[1885,1886],"Jannik Lehmann","David O'Regan","2024-10-03","At GitLab, we [continuously strive to enhance your experience with GitLab Duo Chat]((https://gitlab.com/gitlab-org/gitlab/-/issues/430124)), our AI-powered assistant designed to streamline your development workflows. In this article, we share a series of significant updates that bring even more power, precision, and functionality to GitLab Duo Chat. \n\n## Migration to Claude 3.5 Sonnet\n\nWe are thrilled to announce a major upgrade for GitLab Duo Chat: [the migration of its underlying Large Language Model from Claude 3 Sonnet to the more advanced Claude 3.5 Sonnet](https://gitlab.com/gitlab-org/gitlab/-/issues/468334). This new model brings substantial performance enhancements, offering superior accuracy, context-awareness, and efficiency in AI-driven conversations.\n\nWith Claude 3.5 Sonnet powering GitLab Duo Chat, users can expect more precise and relevant responses. This upgrade ensures Chat remains at the forefront of AI technology, helping your team work more effectively in their daily workflows.\n\n![Screenshot of Chat in VS Code](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098636/Blog/Content%20Images/Blog/Content%20Images/image6_aHR0cHM6_1750098636137.png)\n\nNotice the [code block syntax highlighting](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/1435) in Chat in VS Code.\n\n## Bringing the Slash Command Picker to Chat in the GitLab UI\n\nTo further improve the discovery of GitLab Duo Chat slash commands and make them more quickly accessible to our users, [we’ve introduced the Slash Command Picker UI](https://gitlab.com/gitlab-org/gitlab/-/issues/470703). Now, when you start typing a prompt with `/` in Chat in the GitLab UI, the available slash commands relevant to your current context will be automatically displayed. \n\nThis feature enhances your workflow and acts as the foundation for a growing platform of AI-powered capabilities that we plan to expand in the near future.\n\n![GitLab Duo Chat Slash Command Picker](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098636/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098636138.png)\n\n## Root Cause Analysis integration\n\nGitLab Duo Chat is gaining another powerful feature: [Root Cause Analysis](https://docs.gitlab.com/ee/user/gitlab_duo_chat/examples.html#troubleshoot-failed-cicd-jobs-with-root-cause-analysis). \n\nThis integration allows you to maintain context within Chat while investigating failed pipeline jobs, making it easier to ask follow-up questions and explore the root causes of problems.\n\nYou can access Root Cause Analysis by clicking the \"Troubleshoot\" button at the end of the job log, or you can select the job log portions and then ask Chat with the `/troubleshoot` slash command. With this seamless integration, you have the tools you need to resolve issues more efficiently.\n\n![Root Cause Analysis example in Chat](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098636/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750098636140.png)\n\n## Fix code in the IDE\n\nOne of the latest enhancements to GitLab Duo Chat is the ability to ask it to [fix selected code](https://docs.gitlab.com/ee/user/gitlab_duo_chat/examples.html#fix-code-in-the-ide) within your IDE. This feature, introduced in GitLab 17.3, is available in the Web IDE, VS Code, and JetBrains IDE. It allows you to make specific code fixes by selecting portions of code and using the /fix slash command.\n\nFor example, you can instruct Chat to:\n- Fix grammar mistakes and typos with `/fix grammar mistakes and typos`.\n- Address performance issues using `/fix performance problems`.\n- Solve specific bugs or algorithm-related issues with commands like `/fix duplicate database inserts` or `/fix race conditions`.\n- Resolve code compilation errors with `/fix the build`.\n\nThis feature is designed to help developers quickly resolve common coding issues and improve the quality of their code, all while staying within their familiar IDE environment.\n\nHere is an example for fixing grammar mistakes and improving the language of (code) comments.\n\n![An example for fixing grammar mistakes](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098636/Blog/Content%20Images/Blog/Content%20Images/image5_aHR0cHM6_1750098636142.png)\n\nHere is an example for fixing C code to print the disk usage. Chat correctly suggests missing header includes and provides more help to avoid additional bugs. The source code is available in [the GitLab Duo challenge project](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/fix-c-cli-perf).\n\n![Chat enhancements - image 5](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098636/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098636144.png)\n\n## Explain Vulnerability now in GitLab Duo Chat\n\nAnother highly popular AI-powered feature, [Explain Vulnerability, has been integrated into GitLab Duo Chat](https://gitlab.com/groups/gitlab-org/-/epics/13309). This addition allows you to explore vulnerability details in depth while keeping your Chat context intact. You can ask follow-up questions and engage in more comprehensive discussions directly within the chat environment. You can access this feature by viewing a SAST vulnerability in your project’s Vulnerability Report.\n\nCurrently, this feature supports results from SAST scanners, including [Advanced SAST](https://docs.gitlab.com/ee/user/application_security/sast/gitlab_advanced_sast.html), with plans to extend support to additional scanners soon.\n\n![Sample Vulnerability Report](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098636/Blog/Content%20Images/Blog/Content%20Images/image4_aHR0cHM6_1750098636148.png)\n\n## What's next?\n\nWe're continuously improving GitLab Duo Chat. Some areas we're exploring include:\n- Context is important. We’re prioritizing the integration of [commits](https://gitlab.com/gitlab-org/gitlab/-/issues/468460), [pipeline jobs](https://gitlab.com/gitlab-org/gitlab/-/issues/468461), and [merge requests](https://gitlab.com/gitlab-org/gitlab/-/issues/464587) into Chat’s contextual scope. Additionally, we are looking into [terminal assistance with Chat](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/1423). This expansion will allow Chat to provide more informed and relevant responses based on a broader range of data.\n- Introduce the `/help` slash command. To make navigating Chat’s AI-powered features even more intuitive, we started development on [a /help slash command](https://gitlab.com/gitlab-org/gitlab/-/issues/462122). This new feature will guide users through the available commands and capabilities for easier and faster access to the tools you need.\n- Make Chat available in [supported IDEs](https://docs.gitlab.com/ee/user/gitlab_duo_chat/#supported-editor-extensions). You can follow the development work for Visual Studio in [this epic](https://gitlab.com/groups/gitlab-org/editor-extensions/-/epics/22). \n\nWe look forward to [hearing your feedback on these enhancements](https://gitlab.com/gitlab-org/gitlab/-/issues/430124). Stay tuned for more updates as we continue to evolve [GitLab Duo Chat](https://about.gitlab.com/gitlab-duo/).\n\n> Get started with GitLab Duo Chat today by [signing up for a free  trial](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/?toggle=gitlab-duo-pro).",[717,9,719,848],{"slug":1891,"featured":6,"template":698},"gitlab-duo-chat-get-to-know-productivity-boosting-ai-enhancements","content:en-us:blog:gitlab-duo-chat-get-to-know-productivity-boosting-ai-enhancements.yml","Gitlab Duo Chat Get To Know Productivity Boosting Ai Enhancements","en-us/blog/gitlab-duo-chat-get-to-know-productivity-boosting-ai-enhancements.yml","en-us/blog/gitlab-duo-chat-get-to-know-productivity-boosting-ai-enhancements",{"_path":1897,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1898,"content":1903,"config":1909,"_id":1911,"_type":14,"title":1912,"_source":16,"_file":1913,"_stem":1914,"_extension":19},"/en-us/blog/gitlab-duo-code-suggestions-is-generally-available",{"title":1899,"description":1900,"ogTitle":1899,"ogDescription":1900,"noIndex":6,"ogImage":1860,"ogUrl":1901,"ogSiteName":686,"ogType":687,"canonicalUrls":1901,"schema":1902},"GitLab Duo Code Suggestions is generally available","Learn how our AI-powered workflow helps developers write secure code efficiently.\n","https://about.gitlab.com/blog/gitlab-duo-code-suggestions-is-generally-available","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab Duo Code Suggestions is generally available\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David DeSanto, Chief Product Officer, GitLab\"}],\n        \"datePublished\": \"2023-12-22\",\n      }",{"title":1899,"description":1900,"authors":1904,"heroImage":1860,"date":1906,"body":1907,"category":781,"tags":1908},[1905],"David DeSanto, Chief Product Officer, GitLab","2023-12-22","GitLab Duo Code Suggestions, part of the GitLab Duo suite of AI-powered workflows, is now generally available with GitLab 16.7. [Code Suggestions](https://about.gitlab.com/solutions/code-suggestions/), our generative AI code creation assistant within our DevSecOps platform, helps developers to write secure code more efficiently and assists in improving cycle times by taking care of repetitive, routine coding tasks.\n\nAccording to GitLab's [2023 State of AI in Software Development](https://about.gitlab.com/developer-survey/#ai) report, 83% of DevSecOps professionals said it is essential to implement AI in their software development processes to avoid falling behind, and a majority were interested in using AI for code generation and code suggestions.\n\nAs DevSecOps teams incorporate AI in the software development lifecycle, tapping into easy-to-adopt features like Code Suggestions provides a good entry point to achieve improved efficiency, accuracy, and productivity while not compromising on security and governance.\n\n> [Try Code Suggestions for free](http://about.gitlab.com/solutions/code-suggestions/sales) through February 14.\n\n## Faster development with less context switching\n\nA developer's workload is more than just writing code; it involves extensive context switching to search through documentation, hunt for code examples, and work through trial and error. All of this interrupts the software development process, decreasing time to value.\n\nLeveraging generative AI, Code Suggestions helps boost developers' efficiency and effectiveness by assisting in reducing the time required for coding fundamental functions. It also helps in understanding and extending existing, and sometimes unfamiliar, codebases while helping ensure adherence to security best practices. Code Suggestions includes the following capabilities:\n\n- **Code generation:** automatically generates lines of code, including full functions, from single and multi-line comments as well as comment blocks \n- **Code completion:** automatically proposes new lines of code from a few typed characters\n\nCode Suggestions is available in 15 languages, including C++, C#, Go, Java, JavaScript, Python, PHP, Ruby, Rust, Scala, Kotlin, and TypeScript. GitLab editor extensions can be found in popular IDE marketplaces; VS Code, Visual Studio, JetBrains’ suite of IDEs, and Neovim are all supported. And, of course, Code Suggestions is available within GitLab’s Web IDE, giving developers a quick way to get up and running with GitLab Duo. Support for Code Suggestions is available for self-managed GitLab instances via a secure connection to GitLab cloud infrastructure.\n\nWatch this introduction to Code Suggestions:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/ds7SG1wgcVM?si=9J9gX0qs5De2NXUC\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Discover more AI capabilities with GitLab Duo\n\nOrganizations can use AI to help streamline the entire DevSecOps lifecycle and ship better, more secure, software faster. GitLab Duo has 15 AI-assisted features that support everyone involved in software development. From planning and coding to testing to delivery, there's a [GitLab Duo](https://about.gitlab.com/gitlab-duo/) capability to help. \n\nFor example, [GitLab Duo Vulnerability Resolution](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/index.html#vulnerability-resolution) helps teams remediate vulnerabilities proactively with the assistance of generative AI. In addition, Discussion Summary assists in getting everyone up to speed and aligned on lengthy conversations within [GitLab Enterprise Agile Planning](https://about.gitlab.com/blog/gitlab-enterprise-agile-planning-add-on-for-all-roles/).\n\nOur approach to AI is resonating with our customers. For example, Amado Gramajo, Vice President of Infrastructure & DevOps at Nasdaq, recently shared his excitement about how GitLab Duo will help Nasdaq protect their intellectual property and stay in line with regulatory mandates.\n\nGitLab is the only platform that integrates AI throughout the entire software development lifecycle. As developers become more effective, GitLab helps security and operations team members to keep pace. GitLab has a privacy- and transparency-first approach to AI and [does not use customer code to train AI models](https://docs.gitlab.com/ee/user/project/repository/code_suggestions/index.html#code-suggestions-data-usage). \n\n## Get started with Code Suggestions today\n\nCode Suggestions, which can be trialed for free from December 21 through February 14 (subject to [GitLab’s Testing Agreement](https://handbook.gitlab.com/handbook/legal/testing-agreement/)), is available as an add-on to GitLab subscriptions for an introductory price of $9 USD per user/month. [Contact us today](http://about.gitlab.com/solutions/code-suggestions/sales) to get started with Code Suggestions.\n",[717,994,9],{"slug":1910,"featured":91,"template":698},"gitlab-duo-code-suggestions-is-generally-available","content:en-us:blog:gitlab-duo-code-suggestions-is-generally-available.yml","Gitlab Duo Code Suggestions Is Generally Available","en-us/blog/gitlab-duo-code-suggestions-is-generally-available.yml","en-us/blog/gitlab-duo-code-suggestions-is-generally-available",{"_path":1916,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1917,"content":1923,"config":1927,"_id":1929,"_type":14,"title":1930,"_source":16,"_file":1931,"_stem":1932,"_extension":19},"/en-us/blog/gitlab-duo-code-suggestions-python",{"title":1918,"description":1919,"ogTitle":1918,"ogDescription":1919,"noIndex":6,"ogImage":1920,"ogUrl":1921,"ogSiteName":686,"ogType":687,"canonicalUrls":1921,"schema":1922},"How GitLab Duo Code Suggestions helped me make long car rides fun","AI-powered Gitlab Duo Code Suggestions coupled with Remote Development workspaces helped me create a Python-based guessing game application to keep my daughter entertained.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679869/Blog/Hero%20Images/carride.jpg","https://about.gitlab.com/blog/gitlab-duo-code-suggestions-python","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How GitLab Duo Code Suggestions helped me make long car rides fun\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"}],\n        \"datePublished\": \"2023-08-03\",\n      }",{"title":1918,"description":1919,"authors":1924,"heroImage":1920,"date":1081,"body":1925,"category":781,"tags":1926},[1612],"\nOn long car rides with my daughter I have two options: Let her watch a movie or continuously play a game with her where she tries to guess a random number in my head. I often opt to play the game, but recently, my energy and patience weren't at their peak. This led to a moment of inspiration. Why not develop a simple application that my daughter could play on her own? The only hurdle was that I haven't developed an application in years, and, since then, new languages such as Python have emerged. \n\nWith the help of the AI-powered feature [GitLab Duo Code Suggestions (Beta)](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html), I was able to quickly develop a Python application, despite having no prior knowledge of the programming language.\n\n## How I built the guessing game application\nMy application development journey began by launching the [Web IDE](https://docs.gitlab.com/ee/user/project/web_ide/) powered by VS Code. From there, I navigated to Preferences and [activated Code Suggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-for-an-individual-user), paving the way for my AI-assisted coding session.\n\nThanks to Code Suggestions, I had the flexibility to input code or compose comments in plain text English, and receiving automated code suggestions while typing. For instance, I included only these three comments, ultimately utilizing them to construct the entire application:\n- store a random number between 0 to 10 \n- print a welcome message to Yael, ask to guess a number between 0 to 10 \n- create a loop that will continue until the user guesses the number \n\nTo my surprise, not only did the code suggestions align with my comments, but they also grasped the underlying concept of my application, offering additional code without explicit comments. After making a few minor adjustments, here is the final code for the game:\n\n```python\nimport random\n\n# Store a random number between 0 to 10\nnumber = random.randint(0, 10)\ncounter = 0\n# Print a welcome message to Yael, ask to guess a number between 0 to 10\n\nprint(\"Welcome to the guessing game, Yael!\")\nprint(\"I am thinking of a number between 0 and 10, can you guess what it is?\")\n\n# Create a loop that will continue until the user guesses the number\n\nwhile True:\n   # Get the user's guess\n   guess = int(input(\"Guess my number: \"))\n   counter += 1\n\n\n  # Check if the user's guess is correct\n   if guess == number:\n       # If the guess is correct, print a message and break out of the loop\n       print(\"You guessed it! My number was\", number, \"and it took you\", counter, \"guesses.\")\n       break\n  \n   elif    guess \u003C number:\n       print(\"Your guess is too low.\")\n   else:\n       print(\"Your guess is too high.\")\n\n```\n\nWith the assistance of Code Suggestions, I was able to navigate the intricacies of Python coding, step by step. The suggested code not only aligned perfectly with my intentions, but also expanded my understanding of the programming language, enabling me to build a functional game. \n\nAfter thoroughly testing the guessing game application using the debugging tool in VS Code, I was delighted to find that it worked flawlessly! However, a new challenge arose: How could I make this game accessible to my daughter while in the car?\n\n## How to leverage GitLab Remote Development workspaces Beta\nIf you have young children, you're likely familiar with their constant need for instant gratification. To satisfy my daughter's desire to play the new game on her iPad right away, I needed a solution.\n\nSince the game wasn't available as a mobile or web application, I decided to utilize the power of [GitLab Remote Development workspaces](/blog/quick-start-guide-for-gitlab-workspaces/) to create a mobile environment for her.\n\nThe workspace is a temporary development environment hosted in the cloud, which offers a simple setup process and numerous advantages for developers. Now, you might wonder how this is relevant to our topic. Well, Remote Development workspaces provides a link to access the environment. This became my workaround to allow her to start playing the game immediately within that development environment directly from her iPad.\n\nThis strategy turned out to be the perfect workaround, not only allowing her to enjoy the game but also exposing her to the captivating world of programming.\n\n## Understanding beta features\nWhile my journey of developing a game in Python, with the help of Code Suggestions, has been incredibly valuable, it's important to acknowledge that the feature is currently in its beta phase. As is common with beta features, there are certain considerations to keep in mind. Due to the high demand and ongoing improvements, there may be occasional unscheduled downtime and potential delays in receiving Code Suggestions within IDEs. Additionally, it's worth noting that the suggestions generated by Code Suggestions may occasionally be of lower quality or incomplete. As Beta users, it is crucial to familiarize yourself with the [documented limitations](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html).\n\n## Demo\nThis [click-through demo](https://go.gitlab.com/HplUKw) showcases how I used Code Suggestions to develop the guessing game application. I encourage you to give Code Suggestions a try today as you will have a lot of fun.\n\n## We are looking for your feedback! \nFeedback from Beta users of Code Suggestions is invaluable. The GitLab team eagerly awaits your input, which will play an important role in further enhancing this feature and refining its capabilities. Together, we can shape the future of Code Suggestions and make it even more powerful and reliable. To send feedback, or report on issues, use the [Code Suggestions feedback issue](https://gitlab.com/gitlab-org/gitlab/-/issues/405152). \n\n",[994,719,717,9],{"slug":1928,"featured":6,"template":698},"gitlab-duo-code-suggestions-python","content:en-us:blog:gitlab-duo-code-suggestions-python.yml","Gitlab Duo Code Suggestions Python","en-us/blog/gitlab-duo-code-suggestions-python.yml","en-us/blog/gitlab-duo-code-suggestions-python",{"_path":1934,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1935,"content":1940,"config":1946,"_id":1948,"_type":14,"title":1949,"_source":16,"_file":1950,"_stem":1951,"_extension":19},"/en-us/blog/gitlab-duo-pro",{"title":1936,"description":1937,"ogTitle":1936,"ogDescription":1937,"noIndex":6,"ogImage":1860,"ogUrl":1938,"ogSiteName":686,"ogType":687,"canonicalUrls":1938,"schema":1939}," GitLab Duo Pro combines Code Suggestions, Chat, and organizational controls","AI-powered code completion, code generation, chat, and per-user assignment come to the GitLab DevSecOps Platform as a secure add-on.","https://about.gitlab.com/blog/gitlab-duo-pro","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \" GitLab Duo Pro combines Code Suggestions, Chat, and organizational controls\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Hillary Benson\"},{\"@type\":\"Person\",\"name\":\"Dave Steer\"}],\n        \"datePublished\": \"2024-01-17\",\n      }",{"title":1936,"description":1937,"authors":1941,"heroImage":1860,"date":1943,"body":1944,"category":781,"tags":1945},[1942,886],"Hillary Benson","2024-01-17","> __This blog has been updated to include GitLab Duo Chat (in Beta) as part of the GitLab Duo Pro add-on.__\n\nLast year, we launched GitLab Duo Code Suggestions into general availability as the cornerstone of our GitLab Duo suite of AI capabilities that power DevSecOps workflows. We received incredibly positive feedback from our customers on the ease of use and effectiveness of Code Suggestions' code completion and code generation capabilities. \n\nNow, we are introducing [GitLab Duo Pro](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/), a new package that brings together Code Suggestions, Chat, and organizational control capabilities, ensuring that teams can take advantage of AI exactly where they need it throughout the software development lifecycle.\n\n> [Get started with GitLab Duo Pro](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/) \n\nGitLab Duo Pro, which is available to Ultimate and Premium customers as an add-on, boosts developer efficiency and effectiveness by decreasing the time required to write and understand code. With GitLab Duo Pro, organizations can set up their DevSecOps teams for success by giving them the AI-assisted tools they need to develop secure code faster, improve collaboration, and reduce the security and compliance risks of AI adoption.\n\nGitLab Duo Pro features:\n- Code Suggestions: AI-powered code completion and code generation\n- Chat (Beta): Provides real-time guidance on coding, refactoring, and test generation\n- Privacy-first approach: Your code stays your code — GitLab does not use it for training or fine-tuning AI models\n- Organizational controls: GitLab Duo Pro enables organizations to have greater control over AI by limiting AI usage to approved users only\n\nGitLab Duo Pro is available across SaaS, self-managed, and Dedicated deployments.\n\n## What is GitLab Duo Pro?\n\nWith GitLab Duo Pro, developers can access [Code Suggestions](https://about.gitlab.com/solutions/code-suggestions/) to generate blocks of code from single- and multi-line comments as well as comment blocks. Code Suggestions also autocompletes lines of code from a few typed characters — improving cycle times by securely taking care of repetitive, routine coding tasks.\n\nGitLab Duo Pro also includes [Chat](https://about.gitlab.com/blog/gitlab-duo-chat-beta/) (Beta), which is helpful for technical and non-technical users across the entire software development lifecycle. Chat assists in explaining unfamiliar code, suggesting and generating tests, and simplifying code. You can also use Chat to write code from scratch interactively. Whether you are onboarding to GitLab or you are already an expert, learning how to use GitLab is streamlined with Chat.\n\nOrganizational controls are provided in GitLab Duo Pro for better management of AI capabilities, including per-user assignment, so only approved users can use AI.\n\nGitLab Duo Pro is built with privacy as a critical foundation. Private, non-public customer code stored in GitLab is not used for training or fine-tuning AI models. Learn about [data usage when using GitLab Duo Pro Code Suggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions/index.html#code-suggestions-data-usage).\n\n## Get GitLab Duo Pro today\n\nGitLab Duo Pro is currently available at a special introductory price of $9 USD per user/month to Ultimate and Premium customers. Beginning on February 1, 2024, GitLab Duo Pro will be available for $19 USD per user/month. [Contact us today](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/) to get started with GitLab Duo Pro.\n",[717,496,9],{"slug":1947,"featured":91,"template":698},"gitlab-duo-pro","content:en-us:blog:gitlab-duo-pro.yml","Gitlab Duo Pro","en-us/blog/gitlab-duo-pro.yml","en-us/blog/gitlab-duo-pro",{"_path":1953,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1954,"content":1959,"config":1964,"_id":1966,"_type":14,"title":1967,"_source":16,"_file":1968,"_stem":1969,"_extension":19},"/en-us/blog/gitlab-enterprise-agile-planning-add-on-for-all-roles",{"title":1955,"description":1956,"ogTitle":1955,"ogDescription":1956,"noIndex":6,"ogImage":1627,"ogUrl":1957,"ogSiteName":686,"ogType":687,"canonicalUrls":1957,"schema":1958},"Beyond Devs: GitLab Enterprise Agile Planning add-on for all roles","Our new add-on helps you bring non-technical users into the same DevSecOps platform where engineers build, test, secure, and deploy code.","https://about.gitlab.com/blog/gitlab-enterprise-agile-planning-add-on-for-all-roles","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Beyond Devs: GitLab Enterprise Agile Planning add-on for all roles\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Justin Farris\"},{\"@type\":\"Person\",\"name\":\"Melissa Ushakov\"}],\n        \"datePublished\": \"2023-11-16\",\n      }",{"title":1955,"description":1956,"authors":1960,"heroImage":1627,"date":1416,"body":1962,"category":1397,"tags":1963},[1961,1632],"Justin Farris","Bringing teams together supercharges collaboration. Now you can take this a step further with a new GitLab Enterprise Agile Planning add-on that helps you bring non-technical users into the same DevSecOps platform where engineers build, test, secure, and deploy code.\n\nThe add-on enables you to support cross-team collaboration between developers and non-developers without having to purchase full GitLab licenses for non-engineering team members.\n\nWith additional Agile Planning seats ([$15 per user/month](https://about.gitlab.com/pricing/)), non-engineering team members can participate in planning workflows, measure software delivery velocity and impact with Value Stream Analytics, and utilize executive dashboards to drive organizational visibility. \n\n> This new Enterprise Agile Planning add-on is available to GitLab Ultimate subscriptions. Please contact your [GitLab sales representative](https://about.gitlab.com/sales/) for more information.\n\nAgile planning is most powerful when it extends its reach beyond developers to include stakeholders like product managers, designers, marketing, and sales teams. Here are three ways GitLab can bring value to your entire software development process:\n\n## 1. Scale up as your team grows\n\nGitLab's Enterprise Agile Planning capabilities are designed to grow with your organization. As your teams expand, so do your needs for Agile planning capabilities and cross-team collaboration. As a unified platform with a single data store, GitLab provides different stakeholders within the organization with a curated view of project status, enabling teams to track progress, identify bottlenecks, and make informed decisions. GitLab supports multi-year and cross-team planning workflows, enabling you to do strategic and tactical planning within a single tool. These efficient cross-team workflows help projects move faster from concept to delivery, ensuring a competitive edge in today’s fast-paced digital landscape.\n\n![EpicTree](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749677087/Blog/Content%20Images/EpicTree.png)\n\n> Migrating from Jira? [Learn more here](https://about.gitlab.com/blog/tips-for-a-successful-jira-to-gitlab-migration/).\n\n## 2. Bring compliance closer to development \n\nGitLab ensures that compliance checks and enforcements are automated and seamlessly integrated into software development, making the process more efficient and transparent, and less error-prone. In GitLab, compliance checks like [approval rules](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/rules.html), [compliance pipelines](https://docs.gitlab.com/ee/user/group/compliance_frameworks.html#compliance-pipelines), and [deployment approvals](https://docs.gitlab.com/ee/ci/environments/deployment_approvals.html) are closer to the code as part of developers’ natural workflow, rather than a separate workflow or within a separate issue-tracking tool. With GitLab, reviewers can more easily review the updates in the context of the change and developers can receive more rapid feedback. \n\n![Approvals rules](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749677088/Blog/Content%20Images/Approvals_rules.png)\n\n> Learn more about [GitLab Enterprise Agile Planning](https://about.gitlab.com/solutions/agile-delivery/).\n\n## 3. Eliminate time-consuming configurations\n\nMany Agile planning tools are highly customizable. That can be great for building highly complex and sophisticated workflows, but that complexity can also be a maintenance hazard. Spending time on tool maintenance limits innovation and creates friction in your team’s day-to-day work. GitLab prioritizes convention over configuration to deliver exceptional user experiences that work as-is by default while also giving flexible configuration options so that teams can spend less time on maintenance and more time on innovation. A simplified planning tool within the DevSecOps platform where code is built and delivered drives collaboration, transparency, and trust across all roles, leading to a better cross-team experience to build software faster. \n\n> Are you ready for the Atlassian Server end of life? Learn more about [the benefits of migrating from Atlassian to GitLab](https://about.gitlab.com/move-to-gitlab-from-atlassian/). \n\n## Get started with GitLab Enterprise Agile Planning\n\nIn true GitLab fashion, we continue to [rapidly iterate on our Enterprise Agile Planning capabilities](https://about.gitlab.com/direction/plan/). When you’re ready to get started, [we’re here to help](https://about.gitlab.com/sales/).\n",[1399,9,496],{"slug":1965,"featured":91,"template":698},"gitlab-enterprise-agile-planning-add-on-for-all-roles","content:en-us:blog:gitlab-enterprise-agile-planning-add-on-for-all-roles.yml","Gitlab Enterprise Agile Planning Add On For All Roles","en-us/blog/gitlab-enterprise-agile-planning-add-on-for-all-roles.yml","en-us/blog/gitlab-enterprise-agile-planning-add-on-for-all-roles",{"_path":1971,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1972,"content":1977,"config":1983,"_id":1985,"_type":14,"title":1986,"_source":16,"_file":1987,"_stem":1988,"_extension":19},"/en-us/blog/gitlab-flow-duo",{"title":1973,"description":1974,"ogTitle":1973,"ogDescription":1974,"noIndex":6,"ogImage":839,"ogUrl":1975,"ogSiteName":686,"ogType":687,"canonicalUrls":1975,"schema":1976},"Combine GitLab Flow and GitLab Duo for a workflow powerhouse ","Add the AI-powered capabilities of GitLab Duo to GitLab Flow to boost the efficiency of DevSecOps workflows. This is a guide for deployment in your environment, including a video tutorial.","https://about.gitlab.com/blog/gitlab-flow-duo","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Combine GitLab Flow and GitLab Duo for a workflow powerhouse \",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Cesar Saavedra\"}],\n        \"datePublished\": \"2023-07-27\",\n      }",{"title":1973,"description":1974,"authors":1978,"heroImage":839,"date":1979,"body":1980,"category":781,"tags":1981,"updatedDate":1982},[1475],"2023-07-27","Starting out with DevSecOps requires a well-thought-out workflow, but that can sometimes seem like a daunting challenge. Luckily, there are two things that can help: GitLab Flow and GitLab Duo. GitLab Flow is a prescribed approach to help organizations successfully apply DevSecOps processes. GitLab Duo is a [powerful set of AI-powered capabilities](https://about.gitlab.com/blog/supercharge-productivity-with-gitlab-duo/) within the GitLab DevSecOps Platform that can help organizations develop code, improve operations, and secure software more efficiently. Combined, GitLab Flow and GitLab Duo can help organizations achieve significant improvements in end-to-end workflow efficiency, which can lead to even higher levels of productivity, deployment frequency, code quality and overall security, and production resiliency and availability.\nIn this article, we delve into how GitLab Flow and GitLab Duo can be used together to help organizations be successful with DevSecOps.\n\n> Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Watch today!](https://about.gitlab.com/seventeen/)\n\n## What is GitLab Flow?\nGitLab Flow is a prescribed and opinionated end-to-end workflow for the development lifecycle of applications when using GitLab, an AI-powered DevSecOps platform with a single user interface and a single data model. GitLab Flow is based on best practices and lessons learned from customer feedback and our dogfooding. Furthermore, GitLab Flow spans across the [stages of the DevSecOps lifecycle](https://about.gitlab.com/stages-devops-lifecycle/), forming an efficient workflow with an inner feedback loop for reviewing a specific update and an outer feedback loop for improving the entire application, as well as the development lifecycle itself. \n\n![The GitLab Flow inner and outer loops](https://about.gitlab.com/images/blogimages/gitlab-flow-duo/The-GitLab-Flow-2023-feedback-loops.png)\n\u003Ccenter>The GitLab Flow inner and outer loops\u003C/center>\u003Cp>\u003C/p>\n\nAs you can see by the many stages in GitLab Flow, there is much more to developing software than writing code. Below, we'll dive into each step of GitLab Flow and how GitLab Duo can help. \n\n### Planning\nThe first portion of GitLab Flow is planning, which sits on the outer feedback loop of GitLab Flow. It encompasses issues, merge requests, epics, milestones, iterations, release, release evidence, and more. Let’s cover what roles these components play in GitLab Flow and how GitLab Duo can help.\n\n![Planning - first portion of GitLab Flow](https://about.gitlab.com/images/blogimages/gitlab-flow-duo/The-GitLab-Flow-2023-planning-portion.png)\n\u003Ccenter>Planning - first portion of GitLab Flow\u003C/center>\u003Cp>\u003C/p>\n\n#### Issues\nIssues are where product problems or new features are defined and where team members can collaborate. As an issue is created, you can populate its title and then leverage GitLab Duo **Issue description generation** capability to help enrich the description field, saving time and effort. Because many stakeholders can participate in comment threads on an issue, **Discussion summary** is an AI-powered capability in GitLab Duo that can summarize hundreds of comments on an issue into a concise paragraph so that a stakeholder can quickly get caught up with the conversation, jump into the discussion, and become productive right away.\n\nIssues can be organized and visualized in issue boards, which are a software project management tool that can be used as kanban or Scrum boards. These boards help teams plan, organize, and visualize a workflow for a feature or product release. Different categories of boards can be created and issues can be moved from one board to another one with a simple drag and drop.\n\n#### Merge requests\nMerge requests are where solutions are developed. As release components, issues and merge requests provide the auditability and tracking of application changes done by stakeholders, such as DevOps and platform engineers, system and database administrators, security engineers, and developers. In addition, issues and merge requests are key inputs for the release planning process.\n\nMerge requests can be individually created or created from an issue. Creating a merge request from an issue automatically relates it to that issue so when the merge request is merged its associated issue is automatically closed. Merge requests can also be manually related to an issue.\n\n![Merged merge request will close issue](https://about.gitlab.com/images/blogimages/gitlab-flow-duo/mr-with-its-issue.png)\n\u003Ccenter>Merged merge request will close issue\u003C/center>\u003Cp>\u003C/p>\n\nLike issues, merge requests can include a long list of updates to a feature branch by many stakeholders. Collaborators who need to familiarize themselves with or understand all of the updates included in a merge request can take advantage of the **Merge request summary** capability in GitLab Duo to quickly get caught up on the changes. In addition, collaborators can invoke GitLab Duo **Code Merge request template population**, which uses a pre-created merge request template and automatically fills in the content for sections in it. Description templates provide a way to standardize and optimize collaboration and communication across the development lifecycle and GitLab Duo speeds this up even more!\n\nIssues with the same theme can be grouped together in an epic to organize the work to be done. Epics can have child issues and sub-epics and/or be linked to epics across the organization. Iterations can be used to track sprints of work, and can be manually scheduled or scheduled automatically using GitLab iteration cadences to streamline planning workflows. In addition, iterations include burndown and burnup charts. Burndown charts help track overall progress towards a project's total scope, while burnup charts track the daily total count and weight of issues added to and completed in a given timebox.\n\n#### Milestones\nTeams can use milestones to organize issues and merge requests into a cohesive group with an optional start date and an optional due date. Milestones are typically used to track releases and can track issues and merge requests at a project level or group level. Similar to iterations, milestones also provide burndown and burnup charts to show progress.\n\nMilestones can be associated with a release, whose automated creation generates many artifacts, including the release evidence. The release evidence is an automatically collected snapshot of data that’s related to the release. In addition to test artifacts and linked milestones, job artifacts can optionally be included in the release evidence, which can facilitate internal processes such as external audits.\n\nEpics, milestones, and iterations can be visualized via the Roadmaps page, which helps track release progress and streamline the release process. \n\nOnce the planning takes place, the work towards the resolution of a problem or a new feature can start. This happens in merge requests. Let’s delve deeper into how that happens in GitLab Flow. \n\n> [Learn more by trying GitLab Flow and GitLab Duo](https://gitlab.com/-/trials/new?glm_content=default-saas-trial&glm_source=about.gitlab.com%2Fblog%2F).\n\n### Merge requests and pushing code\n\n![Merge requests and pushing code - second portion of GitLab Flow](https://about.gitlab.com/images/blogimages/gitlab-flow-duo/The-GitLab-Flow-2023-mr-pushing-code-portion.png)\n\u003Ccenter>Merge requests and pushing code - second portion of GitLab Flow\u003C/center>\u003Cp>\u003C/p>\n\nThe second portion of GitLab Flow is related to merge requests and pushing code. As mentioned earlier, merge requests are where solutions are developed through collaboration among stakeholders across the organization. This collaboration can happen in a distributed manner and asynchronously. Participants can take advantage of collaborative capabilities, such as tagging, inline suggestions, inline comments, merge request comments, review threads, and review requests, which can help improve code quality, availability, reliability, and performance. Right after the creation of the merge request is the start of the GitLab Flow inner feedback loop, which is where code and fix pushes, test and scan runs, and collaboration and update reviews take place.\n\n#### Pipelines\nAs updates are applied to a feature branch via merge requests, pipelines — if defined — are automatically executed. Pipelines can have multiple stages and jobs to build and test, and then deploy the application or microservice to a review environment. In that review environment, the updates can be dynamically verified before they are merged to the main branch. This automation helps streamline the application update and review processes.\n\nIn addition, as DevSecOps teams make updates to the application via merge requests, they have a variety of AI-powered capabilities at their disposal. As they write or update code, GitLab Duo **Code Suggestions** recommends code that should come next and the developer can choose to accept or ignore the recommendation. Code Suggestions support code generation via prompts as well as code completion as you type. Code Suggestions can help improve the programming experience by reducing errors and helping developers write code faster, which can help enhance production code quality. Code Suggestions also can lead to higher developer productivity and faster iterations and rollouts.\n\nAs different stakeholders within the organization participate in the development or review of applications, they may encounter code that is poorly documented, complex or difficult to understand, or is written in a programming language unfamiliar to them. The GitLab Duo **Code explanation** capability explains code in natural language so that everyone can understand the code and get up to speed quickly.\n\nMoreover, when updates are committed to the feature branch, the GitLab Duo **Suggested reviewers** capability uses the changes in a merge request and a project’s contribution graph to suggest appropriate reviewers in the reviewer dropdown in the merge request sidebar. The list includes users that are knowledgeable about a specific aspect of the application and would be the best candidates to review the updates. Developers save time by not having to search and identify adequate reviewers, streamlining the review process and avoiding delays and low-quality reviews.\n\nWhen developers make changes to the code, they often don't include a comment in the merge request about the specific changes they made. The GitLab Duo **Merge request summary** capability allows the author of merge request changes to use AI to generate a natural-language comment that summarizes the updates to the code. Reviewers then can better understand the changes and streamline the entire review process\n\nAs reviewers review updates to the code in a merge request, they can create a review block, which can consist of many comments spanning many source files. To help the original author of the updates better understand the feedback provided by the reviewer in a long review block, the GitLab Duo **Code review summary** capability generates a natural-language summary of the reviewer’s feedback. This enables better handoff between authors and reviewers, streamlining the review process.\n\nFurthermore, when developers add new code via a merge request, they can leverage the GitLab Duo **Test generation** capability to use AI to generate unit tests for the new code. This can help to increase developer productivity, improve test coverage, and catch bugs early in the development lifecycle. Developers can also leverage GitLab Duo **Chat**, which is always accessible, to refactor code and generate in-line documentation, e.g. docstrings, for their source code.\n\nWhile pipelines execute on branch updates, they can include automated tests and scans, which helps in shifting security left.\n\n### Shifting security left\n\n![Shifting security left - third portion of GitLab Flow](https://about.gitlab.com/images/blogimages/gitlab-flow-duo/The-GitLab-Flow-2023-shift-sec-left-portion.png)\n\u003Ccenter>Shifting security left - third portion of GitLab Flow\u003C/center>\u003Cp>\u003C/p>\n\nThe third portion of GitLab Flow is shifting security left, which is also part of the GitLab Flow inner feedback loop.\n\nIn addition to DevOps and platform engineers, system and database administrators, and developers, some of the stakeholders collaborating in a merge request may be concerned about security and compliance, which is where automated tests and security scans play a role. Scans can be simply included in a pipeline via readily available templates and/or can be automatically executed within a merge request pipeline. GitLab provides a broad set of built-in security scanners and analyzers that can be leveraged by GitLab Flow, but the DevSecOps platform can also accommodate third-party and custom scanners.\n\nGitLab Flow shifts security left in the pipeline to detect and resolve defects as early as possible in the software development process. It is much simpler and cheaper to fix vulnerabilities early in the development cycle than once the application is in production, where an unscheduled outage can affect your users and revenue.\n\nThe built-in security scanners and analyzers provided by GitLab include: unit testing, infrastructure-as-code (IaC) scanning, static application security testing (SAST) scanners, dependency scanning, secret detection, container scanning, API security, web API fuzz testing, and coverage-guided fuzz testing. In addition, GitLab provides a variety of security dashboards and reports to manage and visualize vulnerabilities, such as the Dependencies list, Security dashboard, Vulnerability Report, and vulnerability pages.\n\nTo help developers and security engineers better understand and remediate vulnerabilities more efficiently, the GitLab Duo **Vulnerability explanation** capability provides an explanation about a specific vulnerability, how it can be exploited, and, most importantly, a recommendation on how to fix the vulnerability. Developers can also take advantage of GitLab Duo **Vulnerability resolution**, which automatically creates a merge request that includes code changes to fix the vulnerability. These AI-powered capabilities can help streamline and optimize the process of securing and hardening an application to prevent vulnerabilities that can be exploited by cyber attacks in production.\n\nBesides SAST scanners, GitLab provides dynamic application security testing (DAST) scanners, which require a running application. When leveraging these scanners, GitLab is capable of automatically provisioning a DAST environment for the DAST scans and then performing a complete cleanup of all resources post-DAST testing. In addition, for running containers, GitLab provides operational container scanning, which scans container images in your cluster for security vulnerabilities.\n\nThe scans mentioned above can be executed automatically within a merge request pipeline or, in some cases, can be scheduled for execution via scan execution and merge request approval policies. These policies can be defined via the GitLab UI or YAML files and are configured in a separate project, allowing segregation of duties for reusability, maintenance, and management. Scan execution policies require that security scans be run on a specified schedule or with the project pipeline, and merge request approval policies take action based on scan results. Security engineers or teams can define these policies to enforce security processes across the organization and GitLab Flow may encounter or leverage these as it spans through its steps.\n\nTo enforce security and compliance across projects in your organization, you can use compliance labels and pipelines. Compliance labels and pipelines can be made mandatory to execute before a project’s own pipeline. With this approach, you can ensure that all teams within your organization meet your security and compliance standards. In addition, you can secure your applications against cyber attacks, conform to government compliance standards, and always be audit-ready.\n\nThe main goal of all of these GitLab Flow security prescriptions is to fix vulnerabilities early in the development cycle rather than once the application is in production, where remediating a vulnerability can prove to be very costly in reputation and revenue.\n\nAs vulnerabilities are mitigated within the GitLab Flow inner feedback loop and more updates are applied to the application in the feature branch, stakeholders need to re-review these updates to ensure that the updates have taken place and no regressions have inadvertently been introduced.\n\n### Continuous review\n\n![Reviews - fourth portion of GitLab Flow](https://about.gitlab.com/images/blogimages/gitlab-flow-duo/The-GitLab-Flow-2023-reviewing-features-portion.png)\n\u003Ccenter>Reviews - fourth portion of GitLab Flow\u003C/center>\u003Cp>\u003C/p>\n\nThe next portion of GitLab Flow is reviewing features, which prescribes the continuous review of applications. Reviewing features involves the ability to stand up a review environment to which the interim application (feature branch) is deployed so that stakeholders can review it in real time and provide feedback. The interim application can then be continuously adjusted until it is ready to be merged to the main branch. GitLab Flow also prescribes the cleanup of all provisioned review environment resources at the moment when the merge request is merged to the main branch.\n\nThis iterative automated review process is part of the inner feedback loop in GitLab Flow. As mentioned above, within the inner feedback loop, GitLab Duo capabilities like Code explanation, Code Suggestions, Suggested reviewers, Merge request summary, Merge request template population, Code review summary, Vulnerability explanation, Vulnerability resolution, and Root cause analysis are prescribed by GitLab Flow to enable a better handoff between authors and reviewers and streamline the entire review process.\n\nThe GitLab Flow inner feedback loop terminates when all review items are addressed and the merge request is approved and merged to the main branch, which triggers the deployment of the application to production.\n\n### Deploying applications and infrastructure\n\n![Deploying - fifth portion of GitLab Flow](https://about.gitlab.com/images/blogimages/gitlab-flow-duo/The-GitLab-Flow-2023-deploy-apps-portion.png)\n\u003Ccenter>Deploying - fifth portion of GitLab Flow\u003C/center>\u003Cp>\u003C/p>\n\nDepending on an organization’s needs, either continuous delivery or continuous deployment is prescribed by GitLab Flow. Whereas continuous delivery is the frequent release of code by triggering the deployments manually (e.g., to production), continuous deployment is the automated release of code (e.g., to production) without human intervention. Let’s cover continuous delivery first.\n\nAs you release your software using continuous delivery, you have a few deployment options. You can establish a freeze window and then deploy using advanced deployment techniques, such as canary, blue/green, timed, and incremental rollouts. Incremental rollouts can lower the risk of production outages delivering a better user experience and customer satisfaction. Advanced deployment techniques can also improve development and delivery efficiency, streamlining the release process.\n\nAs you release your software using continuous deployment, all changes/updates go directly to production. Progressive delivery approaches like feature flags, which allow you to separate the delivery of specific features from a launch, are a good way to reduce risk and manage what functionality to make available to production users. Feature flags support multiple programming languages and allow developer experimentation and controlled testing. You can even use feature flags to roll out features to specific users.\n\nAlthough GitLab supports all these deployment approaches, GitLab Flow allows for the adoption of the approach that best fits the organization and/or specific project needs.\n\n### Monitoring applications and DevSecOps processes\nOnce your application has been deployed to production, it needs to be continuously monitored to ensure its stability, performance, and availability. In addition, as the DevSecOps processes execute, they are measured, providing the opportunity to improve their performance and efficiency. The monitoring capabilities are provided by GitLab and, as such, can be leveraged by GitLab Flow.\n\nFor running containers, GitLab provides operational container scanning (OCS), which scans container images in your cluster for security vulnerabilities. These scans can be automated by scheduling them when to run and any found vulnerabilities are automatically displayed in a security dashboard. The OCS can help keep your cluster applications secure and preempt any cyber attacks that can lead to leaks of private data and even cause unexpected outages.\n\nError tracking allows developers to discover and view errors generated by their application. All errors generated by your application are displayed in the Error Tracking list in GitLab. Error tracking can help with availability and performance of your applications by detecting and resolving unexpected application conditions fast.\n\nGitLab can accept alerts from any monitoring source, including Prometheus, via a webhook receiver. As alerts come in, they are displayed in the GitLab Alerts list, from which you can manually manage them. Alerts can also automatically trigger the creation of incidents, ChatOps, and email messages to appropriate individuals or groups. All these capabilities streamline the alert resolution and management process.\n\nAs incidents are created, due to production problems, they appear in the GitLab Incidents list for incident management. You can manage one or more incidents, sort them, search them, assign them, set their statuses, and even see their SLA preset countdown timer. Moreover, you can create on-call schedules and rotations, escalation policies, and set up paging and notifications to handle incidents. In addition, you can link an incident to an alert so that when the incident is closed, its associated alert is automatically resolved. Incident timelines are another capability for executives and external viewers to see what happened during an incident, and which steps were taken for it to be resolved. All these capabilities streamline the incident management process so that they can be resolved as quickly as possible.\n\nAudit events track important events, including who performed the related action and when in GitLab. These events are displayed in the GitLab Audit Events list and provide, among others, the action that was taken on an object, who did it, and the date and time of its occurrence.\n\nAll the lists and dashboards mentioned above can help preempt out-of-compliance scenarios to avoid penalties as well as streamline audit processes. For your running applications, they generate the data and metrics that can be used in the GitLab Flow outer feedback loop to help improve and optimize your applications and lower the risk of unscheduled production outages.\n\n### Continuous improvement\nWhen applying GitLab Flow, you also have the opportunity to use the insight that GitLab provides in the form of end-to-end process metrics dashboards to continuously improve not just your application but also your software delivery performance. These dashboards and their metrics are auto-generated by GitLab and are always available.\n\n### The Value Stream Analytics dashboard\n\nYou can track and monitor your application development lifecycle through the Value Stream Analytics Dashboard, where you can check project or group statistics over time. This dashboard is customizable but you can get started quickly by creating a value stream using a GitLab-provided default template. The default dashboard displays metrics for each of the pre-defined stages of your value stream analytics, namely Issue, Plan, Code, Test, Review, and Staging, as well as a graph with the average time to completion for each. It also shows the value stream analytics key metrics: lead time, cycle time, new issues, commits, and deploys. You can use these metrics to find areas of improvement in the stages of your value stream.\n\n### DORA metrics dashboard\n\nTo view the performance metrics that measure the effectiveness of your organization’s development and delivery practices, GitLab provides the [DORA](https://about.gitlab.com/solutions/value-stream-management/dora/) (DevOps Research and Assessment) metrics dashboard, which displays four key metrics: Deployment Frequency, Lead Time for Changes, Time to Restore Service, and Change Failure Rate. Deployment Frequency measures how often your organization deploys code to production or releases it to end users. Lead Time for Changes measures how long it takes to go from code committed to code successfully running in production. Time to Restore Service measures the time needed to restore services to the level they were previously, in case of an incident. Finally, Change Failure Rate is the percentage of changes to production or released to users that resulted in a degraded service (for example, a change that caused a service impairment or outage) and subsequently required remediation (required a hotfix, rollback, patch). These four key metrics are outcomes of your current processes and give you the opportunity to improve the factors and capabilities that drive them.\n\n### Customize your dashboard\n\nAnother dashboard is the Value Streams Dashboard, which is a customizable dashboard that enables decision-makers to identify trends, patterns, and opportunities for software development improvements. The metrics shown are the DORA metrics followed by the value stream analytics flow metrics and counts for critical and high vulnerabilities for the month to date, the two preceding months, and the past six months.\n\nGitLab Duo can also help in your continuous improvement efforts. For example, the **Value stream forecasting** capability takes historical data and uses data trends across your development lifecycle to predict the future behavior of your value stream metrics. You can use these predictive analyses in your optimization initiatives.\n\nAll these dashboards and the metrics they report on are part of the GitLab Flow outer feedback loop to help you lower the risk of unscheduled production outages and improve and optimize your applications and DevSecOps workflows.\n\n### AI impact analytics\nTo better understand the impact of the use of GitLab Duo (or AI) along the entire development life cycle, you can check the [AI Impact analytics](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/), from where you can see how the adoption of GitLab Duo Code Suggestions impacts other performance, quality and security metrics. You can visualize the last six months of AI adoption and its impact on other metrics, such as cycle time, lead time, deployment frequency, change failure rate, and critical vulnerabilities over time.\n\nAI impact analytics help to measure adoption, effectiveness and benefits that AI brings to teams and organizations and also to identify areas for improvement.\n\n## Why use GitLab Flow?\nGitLab Flow is a prescribed approach, practiced by our customers and users worldwide, that can provide the following benefits: \n- Higher productivity via the automation capabilities provided by GitLab and its single user interface and data model, all leveraged by GitLab Flow\n- Accurate insights into the end-to-end DevSecOps lifecycle to support continuous improvement\n- Built-in dashboards and metrics that can help you optimize your applications and DevSecOps processes\n- Higher code quality and improved reliability and availability of your applications\n- Better application security through built-in security scanners and capabilities\n- Compliance- and audit-readiness via built-in compliance features\n- Shorter cycle times that can help you increase deployment frequency\n- Continuous review enabled by the GitLab Flow inner feedback loop\n- The GitLab Flow inner feedback loop can help you optimize application updates leading to better code quality and higher reliability and availability of your applications\n- The GitLab Flow outer feedback loop can help you improve your applications as well as the development lifecycle itself\n- High levels of collaboration among stakeholders in your organization\n- Shifting security left to help find vulnerabilities in applications before they make it to production to avoid costly, unscheduled outages\n- Lower risk when deploying to production via the advanced deployment techniques and progressive delivery approaches supported by GitLab\n- AI-powered capabilities that span across the entire development lifecycle and can boost productivity, code quality, continuous improvement, security and compliance, and more\n- Support for cloud-native and non-cloud-native applications\n- Multi-cloud support for hybrid/multi-cloud applications\n- Shifting security left to help you find vulnerabilities in your applications before they make it to production so that you can avoid costly unscheduled outages\n\nHow can you get started with GitLab Flow? Leveraging GitLab Auto DevOps or parts of it is a good starting point for applying GitLab Flow principles to your application development lifecycle.\n\n## GitLab Flow and Auto DevOps\n\n![Auto DevOps - an instantiation of GitLab Flow](https://about.gitlab.com/images/blogimages/gitlab-flow-duo/ado-pipeline.png)\n\u003Ccenter>Auto DevOps - an instantiation of GitLab Flow\u003C/center>\u003Cp>\u003C/p>\n\n[Auto DevOps](https://docs.gitlab.com/ee/topics/autodevops/) applies GitLab Flow throughout all its stages and jobs. You can think of it as a good example for the instantiation of GitLab Flow.\n\nAuto DevOps is a collection of predefined, out-of-the-box CI/CD templates that auto-discover the source code you have. Based on best practices, these templates automatically detect, build, test, deploy, and monitor your applications.\n\nThe Auto DevOps pipeline shifts work left to find and prevent defects as early as possible in the software delivery process. The pipeline then deploys the application to staging for verification and then to production in an incremental/timed fashion.\n\nAuto DevOps gets you started quickly, increasing developer productivity, and it can be easily customized to your needs, with support for the most common programming frameworks and languages. Auto DevOps is modular, customizable, and extensible, which allows you to leverage pieces of it in your pipelines or apply all of it for your application.\n\n## Get started\n[Combine GitLab Flow and GitLab Duo today](https://gitlab.com/-/trials/new?glm_content=default-saas-trial&glm_source=about.gitlab.com%2Fblog%2F) to achieve significant improvements in end-to-end workflow efficiency that can lead to even higher levels of productivity, deployment frequency, code quality and overall security, and production resiliency and availability. \n\nIf you'd like to see a workflow in action that combines GitLab Flow and GitLab Duo and how it can benefit you, watch the following video:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/CKrZ4_tKY4I?si=Kf6QsYFIzKkJZpJd\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n",[109,717,9],"2024-06-18",{"slug":1984,"featured":6,"template":698},"gitlab-flow-duo","content:en-us:blog:gitlab-flow-duo.yml","Gitlab Flow Duo","en-us/blog/gitlab-flow-duo.yml","en-us/blog/gitlab-flow-duo",{"_path":1990,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":1991,"content":1996,"config":2003,"_id":2005,"_type":14,"title":2006,"_source":16,"_file":2007,"_stem":2008,"_extension":19},"/en-us/blog/gitlab-global-devsecops-ai-report",{"title":1992,"description":1993,"ogTitle":1992,"ogDescription":1993,"noIndex":6,"ogImage":942,"ogUrl":1994,"ogSiteName":686,"ogType":687,"canonicalUrls":1994,"schema":1995},"GitLab DevSecOps AI Report: A new software development era","Our survey found that DevSecOps teams are optimistic about AI, but privacy, security, and training emerged as key challenges to successful AI adoption.","https://about.gitlab.com/blog/gitlab-global-devsecops-ai-report","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab Global DevSecOps AI Report: Ushering in a new era of software development\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Ashley Kramer\"}],\n        \"datePublished\": \"2023-09-12\",\n      }",{"title":1997,"description":1993,"authors":1998,"heroImage":942,"date":2000,"body":2001,"category":781,"tags":2002},"GitLab Global DevSecOps AI Report: Ushering in a new era of software development",[1999],"Ashley Kramer","2023-09-12","\nAI has taken the world by storm, creating a tectonic shift across industries and society as a whole. With it, important discussions have emerged about its beneficial applications and the potential for negative repercussions, especially in the field of software development. AI is already changing how software is designed, built, secured, and deployed. With all of the industry buzz around the technology, it’s more important than ever to separate the hype from reality. \n\nThat’s why I’m pleased to share that GitLab has recently released its [Global DevSecOps Report: The State of AI in Software Development](https://about.gitlab.com/developer-survey/#ai). With this survey, we had one goal in mind: to uncover whether AI is living up to its promise. We surveyed more than 1,000 global senior technology executives, developers, and security and operations professionals to understand how organizations use AI in software development today, and what they hope to achieve with it in the future.\n\nMany of the sentiments reflected in the report echo what I hear firsthand from customers across industries and across the world: An eagerness to harness the benefits of AI for business innovation, while remaining cautious of potential risks. \n\nPerhaps unsurprisingly, privacy and security, productivity, and training emerged as key challenges to successful AI adoption. Organizations recognize that the policies and strategies put into place now, and the ways in which we shift our workflows to incorporate AI, will shape the future of software development. \n\nLet’s dive into a few of the key findings.\n\n> Download the full [Global DevSecOps Report: The State of AI in Software Development](https://about.gitlab.com/developer-survey/#ai).\n\n## As the excitement around AI increases, so do security concerns\nSecurity and privacy are top concerns, but they don’t detract from the urgency to implement AI. While 83% of those surveyed said that implementing AI in their software development processes is essential to avoid falling behind, 79% noted that they are concerned about AI tools having access to private information or intellectual property.\n\nThe top concern, by far, is the potential for sensitive information such as customer data being exposed (72%), and nearly half of respondents (48%) said they were concerned that trade secrets may be exposed. \n\nSimilarly, when it comes to the biggest concerns around introducing AI into the software development lifecycle, 48% said that AI-generated code may not be subject to the same copyright protection as human-generated code.\n\nGiven these results, it’s not surprising that 95% of senior technology executives said they prioritize privacy and protection of intellectual property when selecting an AI tool.\n\nTo safely benefit from AI, organizations can avoid pitfalls, including data leakage and security vulnerabilities, by first deploying it in a low-risk environment in their organization. This enables teams to learn by trial and error and build best practices before allowing additional teams to adopt AI, ensuring it scales safely and sustainably. \n\n## AI is poised to increase the productivity of some teams — and increase the workload of others\nDifferent business functions have different goals and use cases for AI, highlighting conflicting areas of opportunity and concern. \n\nOur survey findings show that 40% of security practitioners are worried that AI-powered code generation will increase their workload. However, code generation is just one of many areas where AI can add value. In our survey, developers told us that they spend only 25% of their total time writing code. The rest is spent improving existing code, understanding code, testing and maintaining code, and identifying and mitigating security vulnerabilities. Organizations stand to see major productivity and collaboration benefits by applying AI across the software development lifecycle.\n\t\t\t\nApproximately 50% of respondents expressed interest in AI-powered use cases across the software development lifecycle beyond code generation. In other words, there’s a strong appetite for more — and more integrated — AI spanning the breadth of the software development lifecycle. \n\n## Companies and employees are at odds over how to bridge the AI skills gap \nWhile organizations reported optimism about their company’s use of AI, our survey shows a discrepancy between organizations’ and practitioners’ satisfaction with AI training resources. \n\nDespite 75% of respondents saying their organization provides training and resources for using AI, a roughly equal proportion also said they are finding resources on their own, suggesting that the available resources and training within organizations may be insufficient. \n\nWith AI introducing a new set of skills to learn, 34% of respondents said they need training to use or interpret AI, and developers were significantly more likely to lack confidence in AI-generated output than either security or operations respondents (38% compared to 28% and 28%, respectively). \n\nOrganizations should focus on providing AI training and resources to all job roles and functional areas that will be using AI, and it is especially important to ensure that the resources for development teams are relevant, up to date, and cover the latest AI technologies and applications.\n\n## But wait, there’s more\nThese findings reinforce that for organizations to benefit from AI, it needs to be secure and delivered in a single application that is embedded across the entire software development lifecycle. \n\nThese core tenets guide our vision for the future of the GitLab AI-powered DevSecOps platform and [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our suite of AI capabilities that enables organizations to boost efficiency, productivity, and collaboration. Only by adopting a privacy-first, integrated approach to implementing AI can organizations be confident that their intellectual property is safe while empowering everyone to deliver better, more secure software faster. \n\nTo explore the full report, [download the Global DevSecOps Report: The State of AI in Software Development](https://about.gitlab.com/developer-survey/#ai).\n",[9,717,952],{"slug":2004,"featured":6,"template":698},"gitlab-global-devsecops-ai-report","content:en-us:blog:gitlab-global-devsecops-ai-report.yml","Gitlab Global Devsecops Ai Report","en-us/blog/gitlab-global-devsecops-ai-report.yml","en-us/blog/gitlab-global-devsecops-ai-report",{"_path":2010,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2011,"content":2016,"config":2021,"_id":2023,"_type":14,"title":2024,"_source":16,"_file":2025,"_stem":2026,"_extension":19},"/en-us/blog/gitlab-jetbrains-neovim-plugins",{"title":2012,"description":2013,"ogTitle":2012,"ogDescription":2013,"noIndex":6,"ogImage":839,"ogUrl":2014,"ogSiteName":686,"ogType":687,"canonicalUrls":2014,"schema":2015},"GitLab plugins for JetBrains and Neovim now available in Beta","GitLab plugins for JetBrains IDEs and Neovim are now available in Beta, bringing GitLab Duo Code Suggestions to more software development environments.","https://about.gitlab.com/blog/gitlab-jetbrains-neovim-plugins","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab plugins for JetBrains and Neovim now available in Beta\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kai Armstrong\"}],\n        \"datePublished\": \"2023-07-25\",\n      }",{"title":2012,"description":2013,"authors":2017,"heroImage":839,"date":2018,"body":2019,"category":781,"tags":2020},[1592],"2023-07-25","\n\n_This blog post is the latest in an ongoing series about GitLab's journey to [build and integrate AI/ML into our DevSecOps platform](/blog/ai-ml-in-devsecops-series/). Start with the first blog post: [What the ML is up with DevSecOps and AI?](/blog/what-the-ml-ai/). Throughout the series, we'll feature blogs from our product, engineering, and UX teams to showcase how we're infusing AI/ML into GitLab._\n\nIn June, we shared our plans to [extend AI-powered code suggestions](/blog/extending-code-suggestions/) to more IDEs, thereby continuing to help enhance developer productivity. A few weeks ago, we [announced](/blog/gitlab-visual-studio-extension/) the availability of our [extension for Visual Studio](https://marketplace.visualstudio.com/items?itemName=GitLab.GitLabExtensionForVisualStudio). Now, we're adding support for JetBrains and Neovim with official plugins to further extend the reach of GitLab Duo Code Suggestions and help enhance developer productivity across even more development environments.\n\nThese new GitLab plugins for both JetBrains and Neovim support [GitLab Duo](https://about.gitlab.com/gitlab-duo/) Code Suggestions for both [GitLab SaaS](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-on-gitlab-saas) and [GitLab self-managed](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-on-self-managed-gitlab).\n\n## GitLab for JetBrains IDEs\nYou can download the GitLab for JetBrains plugin from the [JetBrains Plugin Marketplace](https://plugins.jetbrains.com/plugin/22325-gitlab) or from directly within your IDE by visiting `Settings` -> `Plugins` and then searching for `GitLab`. Once you've installed the plugin, follow the [setup instructions](https://gitlab.com/gitlab-org/editor-extensions/gitlab-jetbrains-plugin#setup) to configure authentication and get started.\n\n![JetBrains GitLab Duo Code Suggestions Settings](https://about.gitlab.com/images/blogimages/jetbrains-code-suggestions-settings.png)\n\nYou can verify if the extension is connected and working by checking the status bar icon. If everything looks good, you're ready to start receiving code suggestions as you work. Just start typing and GitLab Duo will automatically provide you suggestions inline. Press `Tab` to accept the suggestions or keep typing to receive new suggestions.\n\n![JetBrains GitLab Duo Code Suggestions](https://about.gitlab.com/images/blogimages/jetbrains-code-suggestions-ghost-text.png)\n\nWe look forward to hearing from you about this initial release! You can provide feedback or report any issues you're having in our [feedback issue](https://gitlab.com/gitlab-org/editor-extensions/gitlab-jetbrains-plugin/-/issues/38).\n\n## GitLab for Neovim\nThe [GitLab for Neovim plugin](https://gitlab.com/gitlab-org/editor-extensions/gitlab.vim) can be found on GitLab and you can [follow the instructions to get started](https://gitlab.com/gitlab-org/editor-extensions/gitlab.vim#getting-started). Once you've downloaded the plugin, there are [configuration options](https://gitlab.com/gitlab-org/editor-extensions/gitlab.vim#configuration) available to help customize your experience.\n\nOnce you've configured the plugin you'll be able to receive suggestions directly within the UI. Check out our demo video below to learn more about the plugin.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube-nocookie.com/embed/PRSPQvbFquU\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nWe're continuing to iterate on our Neovim plugin. You can provide feedback or report any issues you're having in our [feedback issue](https://gitlab.com/gitlab-org/editor-extensions/gitlab.vim/-/issues/22).\n\n## Iterating on AI/ML features\nThese new additions to our family of editor extensions join our existing extensions for [Visual Studio](https://marketplace.visualstudio.com/items?itemName=GitLab.GitLabExtensionForVisualStudio) and [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow). We plan to continue iterating to make the GitLab Duo Code Suggestions experience even better.\n\nWe're also continuing our work on a [GitLab Language Server for Code Suggestions](https://gitlab.com/gitlab-org/editor-extensions/gitlab-language-server-for-code-suggestions), which will allow us to standardize and iterate faster on our IDE extensions, and will enable users of IDEs and code editors to use GitLab Duo Code suggestions even if an official extension isn't available. We look forward to providing more documentation and working with the community on this project in the future.\n\nThese efforts are just the start of how we're incorporating GitLab Duo capabilities throughout the [software development lifecycle](/blog/what-the-ml-ai/) to help GitLab users become more efficient and effective. As we continue to identify painful and time-consuming tasks that are ideal for AI-assisted features, we'll continue to share updates, tutorials, and demos through this blog series.\n\nCheckout GitLabs 16.2 release to see what's new with [Code Suggestions](https://about.gitlab.com/releases/2023/07/22/gitlab-16-2-released/#gitlab-duo-code-suggestions-improvements-powered-by-google-ai).\n\nInterested in using GitLab Duo features? [Join our waitlist](https://forms.gle/9eeUkPJauKsbLaoz5) and we'll keep you updated.\n\nContinue reading our \"[AI/ML in DevSecOps](/blog/ai-ml-in-devsecops-series/)\" series.\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[9,848,719,717],{"slug":2022,"featured":6,"template":698},"gitlab-jetbrains-neovim-plugins","content:en-us:blog:gitlab-jetbrains-neovim-plugins.yml","Gitlab Jetbrains Neovim Plugins","en-us/blog/gitlab-jetbrains-neovim-plugins.yml","en-us/blog/gitlab-jetbrains-neovim-plugins",{"_path":2028,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2029,"content":2035,"config":2041,"_id":2043,"_type":14,"title":2044,"_source":16,"_file":2045,"_stem":2046,"_extension":19},"/en-us/blog/gitlab-named-a-leader-in-2024-gartner-magic-quadrant-for-ai-code-assistants",{"title":2030,"description":2031,"ogTitle":2030,"ogDescription":2031,"noIndex":6,"ogImage":2032,"ogUrl":2033,"ogSiteName":686,"ogType":687,"canonicalUrls":2033,"schema":2034},"GitLab named a Leader in 2024 Gartner Magic Quadrant for AI Code Assistants","In the first Gartner® Magic Quadrant™ for this category, GitLab is recognized for its ability to execute and completeness of vision in AI code assistant technology.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664458/Blog/Hero%20Images/Gartner_AI_Code_Assistants_Blog_Post_Cover_Image_1800x945.png","https://about.gitlab.com/blog/gitlab-named-a-leader-in-2024-gartner-magic-quadrant-for-ai-code-assistants","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab named a Leader in 2024 Gartner Magic Quadrant for AI Code Assistants\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Dave Steer\"}],\n        \"datePublished\": \"2024-08-22\",\n      }",{"title":2030,"description":2031,"authors":2036,"heroImage":2032,"date":2037,"body":2038,"category":781,"tags":2039},[886],"2024-08-22","We’re thrilled to announce that GitLab has been recognized as a Leader in the [Gartner® Magic Quadrant™ for AI Code Assistants](https://about.gitlab.com/gartner-mq-ai-code-assistants/) — the first-ever year of this category. We feel this is an important recognition and we believe it highlights our commitment to delivering AI-powered capabilities that accelerate software delivery, enhance security, and drive innovation for our customers. \n\nAI code assistants go beyond just code generation and completion. They're collaborative partners that boost developer efficiency by improving code quality and continuous learning. By automating routine tasks and providing intelligent suggestions, assistants like GitLab Duo — our suite of AI-powered features — free up developer time to focus on higher-level problem-solving. \n\n![Gartner MQ AI Code Assistants image](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675964/Blog/Content%20Images/AI_Code_Assistants_MQ_graphic__1_.png)\n\n> Download the [2024 Gartner® Magic Quadrant™ for AI Code Assistants report](https://about.gitlab.com/gartner-mq-ai-code-assistants/).\n\n## AI code assistants: Speed, security, and seamless integration\n\nAI code assistants are integral to organizations of all sizes, helping DevSecOps teams develop and deploy secure software faster. However, the true value of AI emerges when it’s integrated across the entire software development lifecycle. Unlike limited AI point solutions, which can lead to fragmented toolchains and data silos, GitLab’s comprehensive platform embeds AI from planning through production, offering holistic visibility and insights via metrics and dashboards.\n\n## The power of GitLab Duo\n\n[GitLab Duo](https://about.gitlab.com/gitlab-duo/) is a comprehensive toolbox of AI capabilities designed to improve the developer experience, shift security left in the development cycle, and strengthen collaboration across Dev, Sec, and Ops teams. Key features include: \n\n* Code Suggestions for code generation and code completion\n* Chat for context-aware, in-app assistance on code explanation, code refactoring, and test generation\n* Vulnerability Explanation to better understand vulnerabilities in code\n* Vulnerability Resolution to help mitigate found vulnerabilities\n* Root Cause Analysis to troubleshoot pipeline issues\n* AI Impact Analytics Dashboard to gain real-time insights and evaluate an organization's AI ROI\n\n## Maximizing ROI with AI \n\nBusiness and engineering leaders need visibility into how AI is being used across the software development lifecycle to assess the ROI of their technology investments. GitLab's [AI Impact Analytics Dashboard](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/) provides that visibility as well as metrics to gauge AI adoption rates, performance improvements, and more.\n\n## Flexibility, privacy, and transparency at the forefront\n\nGitLab customers looking to explore AI-powered capabilities can use GitLab Duo to leverage the power of AI securely across an IDE of choice or a remote development workspace right out of the box, with a flexible pricing structure and a free trial. Also, the [GitLab AI Transparency Center](https://about.gitlab.com/ai-transparency-center/) provides full visibility into our governance and transparency practices. \n\nSoon, organizations will be able to [tailor their AI experience](https://about.gitlab.com/blog/meet-gitlab-duo-workflow-the-future-of-ai-driven-development/) to their strategic and regulatory requirements with model personalization and self-hosted model deployment. Model personalization will allow enterprises to customize GitLab Duo and tap into AI’s full potential in close alignment with their business goals, operational needs, and customer expectations. Self-hosted model deployment ensures that data does not leave an organization's secure environment, reducing the risk of breaches and ensuring compliance for highly regulated industries. \n\n## Leading the future of AI in DevSecOps\n\nGitLab is your partner in AI-driven software development. We equip teams with the tools to build, secure, and deploy software faster. Our commitment to innovation ensures you're always at the forefront of AI advancements. Stay tuned for exciting updates on our roadmap as we continue to revolutionize DevSecOps.\n\n> [Download the 2024 Gartner® Magic Quadrant™ for AI Code Assistants report](https://about.gitlab.com/gartner-mq-ai-code-assistants/).\n\n***Source: Gartner, Magic Quadrant for AI Code Assistants, Arun Batchu, Haritha Khandabattu, Philip Walsh, Matt Brasier, August 2024***\n\n***GARTNER is a registered trademark and service mark of Gartner, Inc. and/or its affiliates in the U.S. and internationally, and MAGIC QUADRANT is a registered trademark of Gartner, Inc. and/or its affiliates and are used herein with permission. All rights reserved.***\n\n***Gartner does not endorse any vendor, product or service depicted in its research publications, and does not advise technology users to select only\nthose vendors with the highest ratings or other designation. Gartner research publications consist of the opinions of Gartner’s research\norganization and should not be construed as statements of fact. Gartner disclaims all warranties, expressed or implied, with respect to this research, including any warranties of merchantability or fitness for a particular purpose.***\n\n***This graphic was published by Gartner Inc. as part of a larger report and should be evaluated in the context of the entire document. The Gartner\ndocument is available upon request from Gartner B.V.***\n",[994,717,9,2040],"research",{"slug":2042,"featured":91,"template":698},"gitlab-named-a-leader-in-2024-gartner-magic-quadrant-for-ai-code-assistants","content:en-us:blog:gitlab-named-a-leader-in-2024-gartner-magic-quadrant-for-ai-code-assistants.yml","Gitlab Named A Leader In 2024 Gartner Magic Quadrant For Ai Code Assistants","en-us/blog/gitlab-named-a-leader-in-2024-gartner-magic-quadrant-for-ai-code-assistants.yml","en-us/blog/gitlab-named-a-leader-in-2024-gartner-magic-quadrant-for-ai-code-assistants",{"_path":2048,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2049,"content":2055,"config":2061,"_id":2063,"_type":14,"title":2064,"_source":16,"_file":2065,"_stem":2066,"_extension":19},"/en-us/blog/gitlab-named-a-leader-in-the-2024-gartner-magic-quadrant-for-devops",{"title":2050,"description":2051,"ogTitle":2050,"ogDescription":2051,"noIndex":6,"ogImage":2052,"ogUrl":2053,"ogSiteName":686,"ogType":687,"canonicalUrls":2053,"schema":2054},"GitLab named 2024 Gartner DevOps Platforms Quadrant leader","GitLab is positioned highest in Ability to Execute and Completeness of Vision, which we believe is recognition of our customers’ success and our continued innovation in the DevOps category.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662523/Blog/Hero%20Images/Gartner_DevOps_Blog_Post_Cover_Image_1800x945__2_.png","https://about.gitlab.com/blog/gitlab-named-a-leader-in-the-2024-gartner-magic-quadrant-for-devops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab named a Leader in the 2024 Gartner Magic Quadrant for DevOps Platforms\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Ashley Kramer\"}],\n        \"datePublished\": \"2024-09-05\",\n      }",{"title":2056,"description":2051,"authors":2057,"heroImage":2052,"date":2058,"body":2059,"category":994,"tags":2060},"GitLab named a Leader in the 2024 Gartner Magic Quadrant for DevOps Platforms",[1999],"2024-09-05","DevOps was originally just a concept, a methodology for delivering software faster by bringing traditionally disparate teams together. It was a response to all the issues caused by the separation of those who built software and those who deployed it.\n\nAt GitLab, we iterated on that concept: Instead of stitching together tools to create a complex DevOps toolchain, a [single DevOps platform](https://about.gitlab.com/platform/) would result in tighter collaboration, greater automation, and more scalable and standardized processes.\n\nWe believe that strategy, which focuses on our customers' success, was correct. In the second iteration of the [Gartner Magic Quadrant for DevOps Platforms](https://about.gitlab.com/gartner-magic-quadrant/), we are once again named a Leader by Gartner and this time, positioned highest on both axes: Ability to Execute and Completeness of Vision.\n\n![Gartner MQ for DevOps Platforms 2024 image](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674334/Blog/Content%20Images/figure1.png)\n\n> Download the [2024 Gartner® Magic Quadrant™ for DevOps Platforms report](https://about.gitlab.com/de-de/gartner-magic-quadrant/).\n\nToday’s software organizations must contend with increasing security threats, complex compliance requirements, and carefully adopting new technologies such as generative AI. This is in addition to simply delivering on their promises of scalable services and continued innovation to their own customers.\n\nGitLab helps our customers face these challenges and become leaders in their own industries. With our AI-powered DevSecOps platform, they are shifting security left, enabling visibility throughout the development lifecycle, and bringing together all the roles and responsibilities needed to deliver the software that powers our world.\n\n## Furthering the DevOps vision\n\nOur work here isn’t done. We will continue to innovate on the DevOps vision and advance our DevSecOps platform in two ways.\n\nFirst, we want to invite even more teams to collaborate on the same platform, with specific features for those involved in [Agile planning](https://about.gitlab.com/blog/categories/agile-planning/), [data science](https://about.gitlab.com/topics/devops/the-role-of-ai-in-devops/), and [observability and application monitoring](https://docs.gitlab.com/operations/observability/).\n\nSecond, we strive to make our platform adoption and deployment options even more flexible to meet our customers’ diverse needs. This includes investing in [GitLab Dedicated](https://about.gitlab.com/dedicated/), our single-tenant, hosted option, so companies in highly regulated industries can have the simplicity of SaaS and the power of all the latest features and capabilities, while adhering to the compliance needs of isolated infrastructure.\n\n## Helping organizations build secure software\n\nBeyond building a better collaboration platform for delivering software, one of the most important things we do at GitLab is help organizations build more secure and compliant software. Our vision here sets us apart, as GitLab integrates [security scanning](https://about.gitlab.com/solutions/security-compliance/) at the point of code commit, not when applications are ready for release. This helps teams catch vulnerabilities sooner, leading to faster release cycles. GitLab also makes compliance easy with policy guardrails and automatically generating [a software bill of materials](https://about.gitlab.com/blog/the-ultimate-guide-to-sboms/).\n\nWe know our customers face more security threats as their own software surface attack area increases. This is why, in the next 12 months, we plan to continue improving our SAST scanners, add additional policy controls, and build [an upcoming native secrets manager](https://about.gitlab.com/blog/gitlab-native-secrets-manager-to-give-software-supply-chain-security-a-boost/).\n\n## Leading with AI throughout the SDLC\n\nOur vision is to also be a leader in AI – both in enabling our customers to build innovative software with AI, and also to do it with privacy-first AI technology. AI represents a generational leap forward with an incredible amount of opportunity when integrated throughout the software development lifecycle. As we innovate, we are doing so responsibly. We’ve heard our customers’ concerns loud and clear: They want [AI with guardrails](https://about.gitlab.com/the-source/ai/velocity-with-guardrails-ai-automation/), [AI that’s transparent](https://about.gitlab.com/ai-transparency-center/), and AI that respects their code and intellectual property.\n\nWe are committed to building [GitLab Duo](https://about.gitlab.com/gitlab-duo/), a suite of AI-powered features for our DevSecOps platform that are all of these: comprehensive, privacy-first, and built to support the entire software development lifecycle.\n\nWe believe this commitment and our GitLab Duo features are why, recently, [Gartner® also named us a Leader in its first Magic Quadrant™ for AI Code Assistants](https://about.gitlab.com/blog/gitlab-named-a-leader-in-2024-gartner-magic-quadrant-for-ai-code-assistants/).\n\nWe are honored by this recognition and see it as a sign to continue listening to you  –  our customers – because that is what drives our vision, product roadmap, and commitment in delivering the best DevSecOps platform.\n\n> Download the [2024 Gartner® Magic Quadrant™ for DevOps Platforms report](https://about.gitlab.com/gartner-magic-quadrant/).\n\n***Source: Gartner, Magic Quadrant for DevOps Platforms, Keith Mann, Thomas Murphy, Bill Holz, George Spafford, August 2024***\n\n***GARTNER is a registered trademark and service mark of Gartner, Inc. and/or its affiliates in the U.S. and internationally, and MAGIC QUADRANT is a\nregistered trademark of Gartner, Inc. and/or its affiliates and are used herein with permission. All rights reserved.***\n\n***Gartner does not endorse any vendor, product or service depicted in its research publications, and does not advise technology users to select only those vendors with the highest ratings or other designation. Gartner research publications consist of the opinions of Gartner’s research organization and should not be construed as statements of fact. Gartner disclaims all warranties, expressed or implied, with respect to this research, including any warranties of merchantability or fitness for a particular purpose.***\n\n***This graphic was published by Gartner Inc. as part of a larger report and should be evaluated in the context of the entire document. The Gartner document is available upon request from Gartner.***",[994,2040,496,1299,9],{"slug":2062,"featured":91,"template":698},"gitlab-named-a-leader-in-the-2024-gartner-magic-quadrant-for-devops","content:en-us:blog:gitlab-named-a-leader-in-the-2024-gartner-magic-quadrant-for-devops.yml","Gitlab Named A Leader In The 2024 Gartner Magic Quadrant For Devops","en-us/blog/gitlab-named-a-leader-in-the-2024-gartner-magic-quadrant-for-devops.yml","en-us/blog/gitlab-named-a-leader-in-the-2024-gartner-magic-quadrant-for-devops",{"_path":2068,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2069,"content":2073,"config":2080,"_id":2082,"_type":14,"title":2083,"_source":16,"_file":2084,"_stem":2085,"_extension":19},"/en-us/blog/gitlab-named-a-leader-in-the-2025-gartner-magic-quadrant-for-ai-code-assistants",{"config":2070,"title":2071,"description":2072},{"noIndex":6},"GitLab named a Leader in the 2025 Gartner Magic Quadrant for AI Code Assistants","GitLab recognized again as a Leader in the 2025 Gartner® Magic Quadrant™ for AI Code Assistants, for vision and execution.",{"title":2071,"description":2072,"heroImage":2074,"authors":2075,"date":2077,"body":2078,"category":994,"tags":2079},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1757675943/q9kb7zfiw1cyxx9fcafp.png",[2076],"Manav Khurana","2025-09-17","GitLab has been recognized for the second time as a Leader in the 2025 Gartner® Magic Quadrant™ for AI Code Assistants. We see this recognition as validation of a key pillar in our broader AI strategy, where intelligent code assistance evolves into comprehensive AI that transforms how entire teams plan, build, secure, and deploy software.\n![2025 Gartner® Magic Quadrant™ for AI Code Assistants](https://res.cloudinary.com/about-gitlab-com/image/upload/v1758121248/jfkmhddve6qvlg79xico.png)\n> [Download the report.](https://about.gitlab.com/gartner-mq-ai-code-assistants/)\n## From AI features to intelligent collaboration \n\nThe Gartner evaluation, we feel, focused on GitLab Duo's generative AI code assistance capabilities. While GitLab Duo began as an AI add-on to the GitLab DevSecOps platform, it laid the groundwork for where we are going today with agentic AI built natively into the GitLab DevSecOps platform. \n\nGitLab Duo Agent Platform enables developers to work alongside multiple AI agents that automate tasks across the software lifecycle. Agents collaborate with each other and with humans, using GitLab’s Knowledge Graph to act with full project context. This empowers teams to move faster while keeping visibility and control. \n\n* **Specialized agents** handle tasks such as code generation, security analysis, and research in parallel. \n\n* **Knowledge Graph** connects agents to a unified system of record across code, issues, pipelines, and compliance data. \n\n* **Human + agent collaboration** happens through natural-language chat and customizable flows, with review and oversight built in. \n\n* **Interoperability with external tools and systems** is supported through Model Context Protocol (MCP) and agent-to-agent frameworks. \n\nWith agents handling routine work under human guidance, teams can move faster, focus on higher-value tasks, and keep projects secure and compliant. \n\n## Secure by design, flexible in practice\n\nThe GitLab Duo Agent Platform is designed to keep security and compliance front and center. Agents run inside GitLab’s trusted DevSecOps environment, with every action visible and reviewable before changes are made. Secure integrations help ensure credentials and sensitive data are handled safely, while interoperability through open standards connects agents to external tools without exposing an organization to risk. \n\nThe platform gives teams confidence that AI is enhancing productivity without compromising governance. Here's how: \n\n* **Developers** can stay focused on complex, high-impact work, while handing off routine tasks to agents for faster results and more granular context delivered through their existing workflows. \n\n* **Engineering leaders** gain visibility into how work moves across the lifecycle, with agents operating within clear guardrails. They also can ensure their teams stay aligned to priorities and simplify onboarding with guided support through agent-driven context and workflows.  \n\n* **IT organizations** maintain control over agent activity with governance features that enforce coding and security policies, offer model selection flexibility, and ensure secure interoperability — all while keeping humans in the loop. \n\n## Leading the move to AI-native development\n\nGitLab continues to build on the vision that began with Duo, and will continue to expand GitLab Duo Agent Platform with new agents, advanced workflows, and more orchestration capabilities. This commitment to innovation ensures you can amplify team productivity on the platform you know and trust. Stay tuned for exciting updates on our roadmap as we continue to revolutionize AI-native DevSecOps. \n\n> [Download the 2025 Gartner® Magic Quadrant™ for AI Code Assistants](https://about.gitlab.com/gartner-mq-ai-code-assistants/) and [try GitLab Duo Agent Platform today](https://about.gitlab.com/gitlab-duo/agent-platform/).\n\n*Source: Gartner, Magic Quadrant for AI Code Assistants, Philip Walsh, Haritha Khandabattu, Matt Brasier, Keith Holloway, Arun Batchu, 15 September 2025* \n\n*GARTNER is a registered trademark and service mark of Gartner, Inc. and/or its affiliates in the U.S. and internationally, and MAGIC QUADRANT is a registered trademark of Gartner, Inc. and/or its affiliates and are used herein with permission. All rights reserved.* \n\n*Gartner does not endorse any vendor, product or service depicted in its research publications, and does not advise technology users to select only those vendors with the highest ratings or other designation. Gartner research publications consist of the opinions of Gartner’s research organization and should not be construed as statements of fact. Gartner disclaims all warranties, expressed or implied, with respect to this research, including any warranties of merchantability or fitness for a particular purpose.* \n\n*This graphic was published by Gartner Inc. as part of a larger report and should be evaluated in the context of the entire document. The Gartner document is available upon request from Gartner B.V.*",[848,994,9],{"featured":91,"template":698,"slug":2081},"gitlab-named-a-leader-in-the-2025-gartner-magic-quadrant-for-ai-code-assistants","content:en-us:blog:gitlab-named-a-leader-in-the-2025-gartner-magic-quadrant-for-ai-code-assistants.yml","Gitlab Named A Leader In The 2025 Gartner Magic Quadrant For Ai Code Assistants","en-us/blog/gitlab-named-a-leader-in-the-2025-gartner-magic-quadrant-for-ai-code-assistants.yml","en-us/blog/gitlab-named-a-leader-in-the-2025-gartner-magic-quadrant-for-ai-code-assistants",{"_path":2087,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2088,"content":2094,"config":2100,"_id":2102,"_type":14,"title":2103,"_source":16,"_file":2104,"_stem":2105,"_extension":19},"/en-us/blog/gitlab-package-roadmap-for-2024",{"title":2089,"description":2090,"ogTitle":2089,"ogDescription":2090,"noIndex":6,"ogImage":2091,"ogUrl":2092,"ogSiteName":686,"ogType":687,"canonicalUrls":2092,"schema":2093},"GitLab Package roadmap for 2024","GitLab is launching new package and container registry features to help enterprise customers consolidate on GitLab for artifact management.\n","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749669103/Blog/Hero%20Images/AdobeStock_243118595.jpg","https://about.gitlab.com/blog/gitlab-package-roadmap-for-2024","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab Package roadmap for 2024\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Tim Rizzi\"}],\n        \"datePublished\": \"2024-01-16\",\n      }",{"title":2089,"description":2090,"authors":2095,"heroImage":2091,"date":2097,"body":2098,"category":848,"tags":2099},[2096],"Tim Rizzi","2024-01-16","_TLDR; In 2024, GitLab will deliver a dependency proxy for Maven, npm, PyPI, and NuGet (stretch). In addition, we'll expand the dependency proxy for containers to work with any external container registry, not just public Docker Hub accounts._\n\n2023 is nearly over. I'd like to take a minute to share some features for [GitLab Package](https://about.gitlab.com/stages-devops-lifecycle/package/) to look forward to in 2024. These new features will enable enterprise customers to consolidate on GitLab for artifact management, and help save money on licensing costs for JFrog/Sonatype and improve the developer experience.\n\n## Package registry\n\nAs the product manager for the Package stage, I have spent the past four years talking to customers and prospects about how they can replace their Artifactory or Sonatype instance with GitLab Package. Although we have helped many smaller organizations to consolidate on GitLab, it's been a challenge to help larger, more complex organizations to do so. Why? Because larger organizations typically need to pull packages from multiple repositories. Artifactory and Nexus offer a feature called virtual registries, which act as a single access point to download, install, or deploy artifacts in the same format from one or more upstream repositories.\n\nThis functionality can:\n- make pipelines faster\n- make pipelines more reliable\n- reduce the cost of data transfer because over time most packages will be pulled from the cache\n\nEach dependency proxy format will give users the ability to add/configure one external repository. \n\nOnce added, when a user tries to install a package using their project-level endpoint, GitLab will first look for the package in the project and, if it's not found, attempt to pull the package from the external repository.\n\nWhen a package is pulled from the external repository, it will be imported into the GitLab project so that the next time that particular package/version is pulled it's pulled from GitLab and not the external repository.\n\nIf the package is not found in their GitLab project or the external repository, GitLab will return an error.\n\n- This feature and all future dependency proxy formats will be in the Premium tier.\n- Project owners will be able to configure this via a project's settings (API or UI).\n- We will support external repositories that require authentication, such as Artifactory or Sonatype.\n\nTo support this theme, we will also likely need to invest in related features, such as those listed in the issues below, which focus on the performance of the registry or giving more fine-grained access control to customers:\n- [Add a dependency proxy scope for GitLab tokens](https://gitlab.com/gitlab-org/gitlab/-/issues/336800)\n- [Improve Package Registry metadata generation](https://gitlab.com/groups/gitlab-org/-/epics/9835)\n- [Package registry authentication token](https://gitlab.com/gitlab-org/gitlab/-/issues/328765)\n\n## Container registry\nToday, GitLab.com is supported by the next-generation container registry and we've seen many performance and reliability improvements.\n\nIn 2024, we will focus on:\n- Getting the [container registry to GA for self-managed customers](https://gitlab.com/groups/gitlab-org/-/epics/5521)\n- [Improving the UI/UX of the container registry](https://gitlab.com/groups/gitlab-org/-/epics/3211)\n- Adding support for [granular access protection for container registries](https://gitlab.com/groups/gitlab-org/-/epics/9825) and [immutable container image tags](https://gitlab.com/gitlab-org/container-registry/-/issues/82)\n- Adding an integration with Google Cloud Platform's Artifact Registry to help [make deploying container images from GitLab to GCP easy](https://gitlab.com/groups/gitlab-org/-/epics/11443)\n\nThis functionality will:\n- help customers to reduce their storage costs\n- make the container registry more performant and reliable\n- make the GitLab team more efficient (by avoiding maintaining two codebases)\n\nWe have exciting plans for 2024! Please follow along as we make the package and container registries more useful, easier to use, and more secure.\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._",[848,994,719,9],{"slug":2101,"featured":6,"template":698},"gitlab-package-roadmap-for-2024","content:en-us:blog:gitlab-package-roadmap-for-2024.yml","Gitlab Package Roadmap For 2024","en-us/blog/gitlab-package-roadmap-for-2024.yml","en-us/blog/gitlab-package-roadmap-for-2024",{"_path":2107,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2108,"content":2114,"config":2122,"_id":2124,"_type":14,"title":2125,"_source":16,"_file":2126,"_stem":2127,"_extension":19},"/en-us/blog/gitlab-pages-features-review-apps-and-multiple-website-deployment",{"title":2109,"description":2110,"ogTitle":2109,"ogDescription":2110,"noIndex":6,"ogImage":2111,"ogUrl":2112,"ogSiteName":686,"ogType":687,"canonicalUrls":2112,"schema":2113},"GitLab Pages features review apps and multiple website deployment","GitLab Pages helps organizations reap the rewards of knowledge management, including better collaboration and accessibility. Learn how to use a new feature, Parallel Deployments.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674550/Blog/Hero%20Images/blog-image-template-1800x945__1_.png","https://about.gitlab.com/blog/gitlab-pages-features-review-apps-and-multiple-website-deployment","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab Pages features review apps and multiple website deployment\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Matthew Macfarlane\"},{\"@type\":\"Person\",\"name\":\"Janis Altherr\"}],\n        \"datePublished\": \"2024-09-23\",\n      }",{"title":2109,"description":2110,"authors":2115,"heroImage":2111,"date":2118,"body":2119,"category":848,"tags":2120,"updatedDate":2121},[2116,2117],"Matthew Macfarlane","Janis Altherr","2024-09-23","[GitLab Pages](https://docs.gitlab.com/ee/user/project/pages/) has long been\na popular choice for hosting static websites, allowing users to showcase\ntheir projects, blogs, and documentation directly from their repositories.\n\n\nBefore GitLab 17.4, you could only have a single version of your GitLab\nPages website. So you couldn’t preview your changes or have multiple\nversions of your website deployed simultaneously. Now, with a Premium or\nUltimate license, you can do both!\n\n\n### Introducing Parallel Deployments\n\n\nWith Parallel Deployments, users can now easily preview changes and manage\nmultiple environments for their GitLab Pages sites. This enhancement allows\nseamless experimentation with new ideas, enabling users to confidently test\nand refine their sites. By catching any issues early, users can ensure the\nlive site remains stable and polished, building on the already great\nfoundation of GitLab Pages.\n\n\n### Why Parallel Deployments is a game-changer\n\n\n1. **Version control made easy**\\\n   If your project involves software development or documentation that covers multiple versions (such as user guides for different software releases), Parallel Deployments makes it easy to manage. Or you can use the feature to localize your website for different languages.\n2. **Flexibility to experiment**\\\n   Want to try out a new design or feature? Parallel Deployments lets you experiment freely. You can create a separate version of your site to test new ideas without impacting the current site. This flexibility encourages creativity and continuous improvement.\n\n### How to add review apps to your GitLab Pages project\n\n\nTo add a review app to your GitLab Pages project, edit your `.gitlab-ci.yml`\nfile to create a deployment for each merge request (MR). Let’s assume you\nstart with a `.gitlab-ci.yml` file somewhat like this:\n\n\n```yaml\n\ncreate-pages:\n  stage: deploy\n  script:\n    - npm run build\n  pages: \n    publish: dist # the name of the folder containing the pages files\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # only run this job when there's a commit to the default branch\n```\n\n\nTo also run the pages pipeline when there’s an MR being opened or updated,\nwe can add another rule to `pages.rules`:\n\n\n```yaml\n\n- if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n\n```\n\n\nIf we only add this rule, however, each Pages job will always replace the\nmain deployment – each time an MR is opened! You likely don’t want that to\nhappen.\n\n\nTo provide each individual deployment with its own URL, we’ve introduced the\nnew `pages.path_prefix` property.\n\n\nA Pages deployment with this configuration...\n\n\n```yaml\n\ncreate-pages:\n  script:\n    - ...\n  pages:\n    ...\n    path_prefix: my-review-app\n```\n\n\n...will be available at\n`https://my-pages-app-7fe824.gitlab.io/my-review-app`, or, with unique\ndomains disabled, `https://my-group.gitlab.io/my-project/my-review-app`.\n\n\nBut there’s no need to hardcode the path_prefix. You can dynamically\ngenerate it using CI variables. That’s particularly useful for review apps –\nto create a path for each MR, use the `CI_MERGE_REQUEST_IID variable`:\n\n\n```yaml\n\ncreate-pages:\n  script:\n    - ...\n  pages:\n    ...\n    path_prefix: mr-$CI_MERGE_REQUEST_IID\n```\n\n\nAn MR with the ID 114 would then automatically create a deployment at\n`https://my-pages-app-7fe824.gitlab.io/mr-114`.\n\n\nWith those concepts at hand, we’d like our pipeline to dynamically create\neither a main deployment for the default branch, or a path_prefixed-review\napp for MR events.\n\n\nFirst, let’s add a `create-pages-review-app` job to our pipeline config:\n\n\n```yaml\n\ncreate-pages-deployment:\n  # This job will create a pages deployment without path_prefix\n  # when there is a commit to the default branch\n  stage: deploy\n  script:\n    - npm run build\n  pages: \n    publish: dist \n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n\ncreate-pages-review-app:\n  # This job will create a pages deployment with a path_prefix\n  # when there a merge request is created or updated.\n  stage: deploy\n  script:\n    - npm run build\n  pages:\n    publish: dist \n    path_prefix: 'mr-$CI_MERGE_REQUEST_IID' # Prefix with the mr-\u003Ciid>, like `mr-123`\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n```\n\n\nNow you’re creating a deployment both when pushing to the default branch,\nand prefixed parallel deployments when creating or updating MRs!\n\n\nFor the best experience, add the URL to the environment job property. This\nwill add a link to the review app to the MR page:\n\n\n```yaml\n\ncreate-pages-deployment:\n  # This job will create a pages deployment without path_prefix\n  # when there is a commit to the default branch\n  stage: deploy\n  script:\n    - npm run build\n  pages: \n    publish: dist \n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n\ncreate-pages-review-app:\n  # This job will create a pages deployment with a path_prefix\n  # when there a merge request is created or updated.\n  stage: deploy\n  script:\n    - npm run build\n  pages:\n    publish: dist \n    path_prefix: 'mr-$CI_MERGE_REQUEST_IID' # Prefix with the mr-\u003Ciid>, like `mr-123`\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n  environment:\n    name: \"Pages Review MR ${CI_MERGE_REQUEST_IID}\"\n    url: $CI_PAGES_URL\n```\n\n\nCongratulations, you’ve now set up MR review apps for your Pages site.\n\n\n## How to deploy documentation for different versions of your product\n\n\nThe Parallel Deployments feature is also a useful tool if you maintain the\ndocumentation of multiple versions of your software simultaneously.\n\n\nThe below CI config will not only create a pages deployment when there is a\ncommit to the default branch, but also for any commit to branches named\n`v1`, `v2`, or `v3`.\n\n\n```yaml\n\ncreate-pages:\n  stage: deploy\n  script:\n    - ...\n  variables:\n    PAGES_PREFIX: \"$CI_COMMIT_BRANCH\" # Use the branch name by default\n  pages:\n    path_prefix: \"$PAGES_PREFIX\" # use whatever value is set in the variable\n  environment:\n    name: \"Pages ${PAGES_PREFIX}\"\n    url: $CI_PAGES_URL\n  artifacts:\n    paths:\n    - public\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n      variables:\n        PAGES_PREFIX: '' # No prefix\n    - if: $CI_COMMIT_BRANCH == 'v1'\n    - if: $CI_COMMIT_BRANCH == 'v2'\n    - if: $CI_COMMIT_BRANCH == 'v3'\n```\n\n\nBy using the `$CI_COMMIT_BRANCH` variable as the path_prefix value, each of\nthese branches will deploy their documentation to their own sub-path of your\nwebsite:\n\n\n- The branch named v1 has its docs published to \u003Cmy-domain>/v1.\n\n- The branch named v2 has its docs published to \u003Cmy-domain>/v2.\n\n- The branch named v3 has its docs published to \u003Cmy-domain>/v3.\n\n\nA new commit to one of these branches will then trigger a new deployment to\nits respective path, keeping the documentation of multiple versions up to\ndate.\n\n\nThe Parallel Deployments feature is a significant upgrade to GitLab Pages,\noffering a more flexible and efficient way to manage your knowledge. Whether\nyou're working on a small project or a large-scale site with multiple\nversions, this new capability will make your workflow smoother and more\nefficient\n\n\n> Visit our [Parallel Deployments\ndocumentation](https://docs.gitlab.com/ee/user/project/pages/#create-multiple-deployments)\nto get started today!\n\n\n### Feedback\n\n\nShare your ideas and other comments in our [feedback\nissue](https://gitlab.com/gitlab-org/gitlab/-/issues/482040)!\n",[1399,109,9,719,848,827],"2025-04-09",{"slug":2123,"featured":6,"template":698},"gitlab-pages-features-review-apps-and-multiple-website-deployment","content:en-us:blog:gitlab-pages-features-review-apps-and-multiple-website-deployment.yml","Gitlab Pages Features Review Apps And Multiple Website Deployment","en-us/blog/gitlab-pages-features-review-apps-and-multiple-website-deployment.yml","en-us/blog/gitlab-pages-features-review-apps-and-multiple-website-deployment",{"_path":2129,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2130,"content":2136,"config":2143,"_id":2145,"_type":14,"title":2146,"_source":16,"_file":2147,"_stem":2148,"_extension":19},"/en-us/blog/gitlab-rezilion-integration-reduces-vulnerability-backlog-identifies-exploitable-risks-to-fix",{"title":2131,"description":2132,"ogTitle":2131,"ogDescription":2132,"noIndex":6,"ogImage":2133,"ogUrl":2134,"ogSiteName":686,"ogType":687,"canonicalUrls":2134,"schema":2135},"Reducing vulnerability backlog with Rezilion and GitLab","The native integration helps developers detect and remediate vulnerabilities that are exploitable early on in the development process.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749668437/Blog/Hero%20Images/faster-cycle-times.jpg","https://about.gitlab.com/blog/gitlab-rezilion-integration-reduces-vulnerability-backlog-identifies-exploitable-risks-to-fix","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How GitLab's integration with Rezilion reduces vulnerability backlog and identifies exploitable risks\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Baksheesh Singh Ghuman\"}],\n        \"datePublished\": \"2022-03-23\",\n      }",{"title":2137,"description":2132,"authors":2138,"heroImage":2133,"date":2140,"body":2141,"category":694,"tags":2142},"How GitLab's integration with Rezilion reduces vulnerability backlog and identifies exploitable risks",[2139],"Baksheesh Singh Ghuman","2022-03-23","\n\nRezilion and GitLab are partnering on an integration that will help resolve the longstanding tension between developers and security teams in organizations around the world. DevOps wants to write code and push new products to innovate and stay competitive. Security teams want to ensure applications are secure and unexploitable so that their organizations stay safe. These two desires often collide as DevOps wants to keep moving and security is seen as a bottleneck to their progress.\n\nTo help developers detect and remediate vulnerabilities early on in the development process and release products quickly and securely, Rezilion’s DevSecOps technology is now natively integrated with GitLab CI.\n\nSome of the key use benefits of this integration are the ability to:\n\n- [Reduce vulnerability backlog by up to 70%](https://www.rezilion.com/wp-content/uploads/2019/11/Rezilion-CARTA-Runtime-Vuln-Memory-Analysis-Report.pdf) and reduce patching efforts by identifying unexploitable vulnerabilities so that developers can fix what matters most and not waste time. \n\n- Prioritize what matters most in your environment to help save developers time and deliver better products faster.\n\n- Remediate significantly faster by integrating Rezilion's capabilities directly into the GitLab development workflow. This allows you to address real threats in a timely manner.\n\n- Gain actionable insights within the GitLab CI pipeline. Non-exploitable vulnerabilities are marked as “false positives” and can be dismissed, while issues can be easily assigned to fix the exploitable ones.\n\n- Identify software components with a dynamic Software Bill of Materials (SBOM), including open source components and their loaded/unloaded status for quick risk view.\n\n- Shift security left by validating vulnerabilities early in the process (right after the build, in the CI pipeline itself as part of tests that are running there). \n\nResults are available within the GitLab Security Dashboard and Vulnerability Management for use within the CI pipeline, at the project level, and across groups of projects.\n\n## Too many vulnerabilities, not enough focus\n\nA growing vulnerability backlog coupled with a lack of clarity on which vulnerabilities to fix – and when – can lead to a range of challenges, including:\n\n- Wasting developers' time\n- Delaying time to market\n- Increasing the likelihood of exploitation due to long remediation timelines\n\nA large vulnerability backlog takes up too much time. Remediating everything is not always realistic, practical, or secure. That’s why Rezilion’s native integration with GitLab CI allows teams to focus on fixing what matters most.\n\n## Enhanced runtime validation to fix what is exploitable \n\nBy integrating Rezilion’s capabilities into GitLab CI, developers now have a more complete and convenient security solution to restore focus on innovation. \n\nUsing Rezilion’s enhanced runtime validation, customers save time by scanning for vulnerabilities, filtering out scan results that do not pose a risk, building efficient remediation plans, and continuing to focus on seamlessly innovating software.\n\nCustomers can also easily visualize what software components are present in their environment – which are loaded to memory and therefore exploitable – by accessing their dynamic SBOM directly from the GitLab UI platform.\n\n\n![Rezilion Enhanced Vulnerability Validation funnel](https://about.gitlab.com/images/blogimages/rezilionfigure1.png){: .shadow}\n\nFigure 1: Enhanced Vulnerability Validation helps you focus on and fix what matters most\n{: .note.text-center}\n\n\n\n![Vulnerability report](https://about.gitlab.com/images/blogimages/rezilionfigure2.png){: .shadow}\n\nFigure 2: The vulnerability report shows a list of vulnerabilities in your pipeline and marks the false positives. Additionally, each row shows when it was detected, its status, severity, and details.\n{: .note.text-center}\n\nWe believe this integration will be very impactful for CISOs, product security team members, and developers who need to focus on innovating and product delivery, without delays due to a vulnerability backlog and cumbersome remediation timelines.\n\nCheckout this video to see Rezilion's GitLab integration in action:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/FXPwn7h8sBc\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nGet started today with a free trial of both \u003Ca href=\"/free-trial/\" data-ga-name=\"free trial\" data-ga-location=\"blog inline\">GitLab Ultimate\u003C/a> and [Rezilion](https://www.rezilion.com/sign-up-for-30day-free-trial/) to experience more efficient software vulnerability management.\n\n\n\n",[694,9,233,994],{"slug":2144,"featured":6,"template":698},"gitlab-rezilion-integration-reduces-vulnerability-backlog-identifies-exploitable-risks-to-fix","content:en-us:blog:gitlab-rezilion-integration-reduces-vulnerability-backlog-identifies-exploitable-risks-to-fix.yml","Gitlab Rezilion Integration Reduces Vulnerability Backlog Identifies Exploitable Risks To Fix","en-us/blog/gitlab-rezilion-integration-reduces-vulnerability-backlog-identifies-exploitable-risks-to-fix.yml","en-us/blog/gitlab-rezilion-integration-reduces-vulnerability-backlog-identifies-exploitable-risks-to-fix",{"_path":2150,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2151,"content":2156,"config":2162,"_id":2164,"_type":14,"title":2165,"_source":16,"_file":2166,"_stem":2167,"_extension":19},"/en-us/blog/gitlab-security-hardening-documentation",{"title":2152,"description":2153,"ogTitle":2152,"ogDescription":2153,"noIndex":6,"ogImage":684,"ogUrl":2154,"ogSiteName":686,"ogType":687,"canonicalUrls":2154,"schema":2155},"The backstory on GitLab's security hardening documentation","GitLab has detailed documentation about how to harden your instance, now as a part of GitLab itself. Here's how it came to be.","https://about.gitlab.com/blog/gitlab-security-hardening-documentation","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"The backstory on GitLab's security hardening documentation\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Mark Loveless\"}],\n        \"datePublished\": \"2023-08-01\",\n      }",{"title":2152,"description":2153,"authors":2157,"heroImage":684,"date":2159,"body":2160,"category":694,"tags":2161},[2158],"Mark Loveless","2023-08-01","\nRecently, my fellow Security team member [Ayoub Fandi](https://gitlab.com/ayofan) released an excellent blog post entitled “[How to harden your self-managed GitLab instance](https://about.gitlab.com/blog/how-to-harden-your-self-managed-gitlab-instance/),” which featured seven steps for helping to lock down your environment. Ayoub’s blog post was based, in part, on early drafts of research into hardening I had been working on. I had no idea how long it would take me to reach a point where I could finally say this, but those original drafts are now a [part of GitLab documentation](https://docs.gitlab.com/ee/security/hardening.html).\n\n## Hardening your GitLab instance\nThe goal of the hardening documentation is for DevSecOps teams to be able to apply security controls and make sure your data and your GitLab instance are protected.\n\nHere's what I will cover:\n- the origins of the hardening documentation\n- field research, including a few attack scenarios\n- bringing an instance online\n- insight into when to use hardening, specifically how to do a bit of threat modeling and get the basics sorted before diving deep into full hardening \n\n## Origins of the hardening documentation\nThe idea for creating extensive hardening documentation started with a blog post I wrote three years ago called “[GitLab instance: Security best practices](https://about.gitlab.com/blog/gitlab-instance-security-best-practices/).\" This became a rather popular reference for GitLab customers asking about securing their self-managed instance (and even a SaaS deployment).\n\nAs I participated in other security efforts around Gitlab, such as [FedRAMP certification](https://about.gitlab.com/handbook/security/security-assurance/dedicated-compliance/fedramp-compliance.html), [compliance requirements](https://about.gitlab.com/handbook/security/security-assurance/security-compliance/certifications.html), and general [security concerns](https://about.gitlab.com/handbook/security/), I realized we needed more support materials focused on the \"Sec\" in DevSecOps.\n\nThe hardening project was born from this -  based largely off of an instance I had loaded up in 2020 and was using at home. During all of this time, from 2020 until now, I took notes, performed tests, had hacker friends and work colleagues poke and prod at this home system, and, then took even more notes. No doubt, the information I learned would be a huge benefit to GitLab users so I opted to create recommendations that could be updated frequently and accessible directly from a GitLab instance via the Help menu. \n\n## Field research\nI've been a security professional for well over a couple of decades and have had my own domain online since 1997, using five static IP addresses in my house. This deployment includes web services, a Mastodon instance, and a mail server. These systems have been used by a few close hacker friends during this time as a testbed, a place to converse and exchange ideas, and a great educational environment. A few years ago, I thought it would be fun for this group to have its own private GitLab instance called [Blackhole](https://blackhole.nmrc.org/). We could work on coding projects together, collaborate, and, since I worked at GitLab, I could use it for testing of a standalone instance for certain work-inspired issues.\n\nHaving live servers up with dedicated and static IP addresses means that, yes, these servers are under pretty much constant attack. Because of this clustering of security friends on these systems, we’ve even been targeted by more sophisticated attackers, up to and including nation states. A perfect test environment for real-world attack scenarios.\n\n### Attack scenarios\nLike many in the security field, over the years I’ve seen a number of attacks firsthand, so I made a list of things I needed for hardening against attacks. After doing some [threat modeling](https://about.gitlab.com/handbook/security/threat_modeling/), I noted the following three areas of concern:\n1. **Opportunistic intruders (okay, who am I kidding, [script kiddies](https://www.techtarget.com/searchsecurity/definition/script-kiddy-or-script-kiddie)).** These types of attacks are typically composed of easy-to-use scripts against known vulnerable applications. This has happened to me. Within five minutes of installation of an odd web-based application, while still reading the documentation and wondering if the apparently vulnerable software was actually working, it was compromised. So I had to assume immediate attacks would happen if I loaded this up on a live system exposed to the open internet.\n2. **Layered or chained attacks.** This is when an attacker takes advantage of a particular sub-component that is exposed to the internet, and while the sub-component might not allow for full system access, it could allow for access to another sub-component with access to data. I was determined to disable or secure as much as possible, leaving as few exposed ports or running services as possible.\n3. **Advanced persistent threat ([APT](https://en.wikipedia.org/wiki/Advanced_persistent_threat)) attackers.** They have repeatedly gone after my former employers, and as they learned who their employees were, home systems would become targets, and [mine were no exception](https://www.markloveless.net/blog/2021/6/8/advancing-persistently-against-apt). To this day, I receive an APT attack attempt every few months. Knowing that one tactic of APT attackers is supply chain attacks, having a DevSecOps platform shared by hackers could be seen as a delicious target, so security had to be top of mind.\n\n## Bringing an instance online\nAs I installed Blackhole, I first configured the firewall at the operating system level to close off all of the ports from public access, only allowing access from my internal network. As a rule, my perimeter router allows all traffic in for those five static IP addresses, with each system following strict firewall rules using the operating system’s firewall capabilities. Most of these five systems cannot even talk to each other, or only have the bare minimum connectivity configured to enable functionality. As I was monitoring traffic to my public systems via my perimeter router, in less than 10 minutes, I started seeing port scans against Blackhole’s IP address, well before it had even finished installation of the Linux operating system. I was glad the firewall was up and running from the start.\n\nAs GitLab was installed and Blackhole came up in its state as a GitLab instance, I started going through the various settings and making sure that things were locked down as tight as possible. Anything I wasn’t using was disabled. This applied to the underlying operating system as well as the GitLab software itself. When I felt good enough about it, I adjusted the firewall settings to open things up ever so slightly, and the system has been under near constant attack since.\n\n## When to use the hardening documentation\nGitLab is a comprehensive DevSecOps platform that can handle all kinds of security scenarios. GitLab the company uses the product to not only develop the platform, but we also run the company off of it. The feature-rich platform can be configured in many different ways. Keeping that in mind, note that one setup might be set up to be more secure than another simply because of the environment it needs to be included in. There are drastically different configuration choices for an environment that is publicly accessible vs. one that is only accessible from employee workstations, or  a large enterprise with employees located on multiple continents vs. a small business' single server deployment.\n\nHardening, therefore, is dependent on your unique environment, and requires you to understand the threats you need to mitigate against, and account for any regulatory and compliance requirements to which you must adhere. However, there are a few common steps that can lead you through the process.\n\n### Start with the basics\nThe first recommendation is to start with a few basics. Make sure you have some ground rules established in your organization such as password standards, software upgrade schedules, and compliance requirements. This will make it easier as you move through the process. Understand the threats your organization has faced in the past, and the potential threats you could face in the future. I wrote a blog post on [threat modeling](https://about.gitlab.com/handbook/security/threat_modeling/) and [we use it internally](https://about.gitlab.com/handbook/security/threat_modeling/howto.html) as well.\n\n### Full hardening\nI’d recommend reading [Ayoub’s blog post](https://about.gitlab.com/blog/how-to-harden-your-self-managed-gitlab-instance ) and follow the seven steps he puts forward. In many cases, after you’ve finished Ayoub’s blog post you will have enough to meet your security needs right there. If you need more, delve into the [hardening recommendations documentation](https://docs.gitlab.com/ee/security/hardening.html). Adapt it as needed to meet your organization’s security demands, and explore the possibilities to increase the security of your environment. Note that these recommendations are not limited to just GitLab settings, but also includes a few recommendations for the underlying operating system itself.\n\n### Share your feedback\nIf you have ideas for more security tips and tricks or questions regarding the hardening documentation, please open an issue on GitLab. We’d love to hear from you and welcome feedback and contributions! And if you want to learn more about how we do security at GitLab, review the [security section](https://about.gitlab.com/handbook/security/) of the handbook.\n",[694,953,9],{"slug":2163,"featured":6,"template":698},"gitlab-security-hardening-documentation","content:en-us:blog:gitlab-security-hardening-documentation.yml","Gitlab Security Hardening Documentation","en-us/blog/gitlab-security-hardening-documentation.yml","en-us/blog/gitlab-security-hardening-documentation",{"_path":2169,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2170,"content":2176,"config":2183,"_id":2185,"_type":14,"title":2186,"_source":16,"_file":2187,"_stem":2188,"_extension":19},"/en-us/blog/gitlab-supports-banks-in-navigating-regulatory-challenges",{"title":2171,"description":2172,"ogTitle":2171,"ogDescription":2172,"noIndex":6,"ogImage":2173,"ogUrl":2174,"ogSiteName":686,"ogType":687,"canonicalUrls":2174,"schema":2175},"GitLab supports banks in navigating regulatory challenges","Learn the upcoming changes to key frameworks, how they impact organizations, and the DevSecOps platform features that can help address them.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664874/Blog/Hero%20Images/AdobeStock_880918603.jpg","https://about.gitlab.com/blog/gitlab-supports-banks-in-navigating-regulatory-challenges","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab supports banks in navigating regulatory challenges\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"George Kichukov\"},{\"@type\":\"Person\",\"name\":\"Allie Holland\"}],\n        \"datePublished\": \"2025-01-09\",\n      }",{"title":2171,"description":2172,"authors":2177,"heroImage":2173,"date":2180,"body":2181,"category":694,"tags":2182},[2178,2179],"George Kichukov","Allie Holland","2025-01-09","The risk of cyber attacks in the banking industry has reached unprecedented levels. Studies by the [International Monetary Fund](https://www.imf.org/-/media/Files/Publications/GFSR/2024/April/English/ch3.ashx) reveal that the financial sector is particularly vulnerable to cyber threats, with nearly one-fifth of reported incidents in the past two decades targeting this industry alone. As these threats continue to escalate, they drive the need for a regulatory response, prompting the banking and financial services industry to prepare for significant changes. GitLab enables financial institutions to proactively tackle these challenges, supporting banks on their regulatory journey while ensuring the operational resilience needed to protect the sensitive data pervasive throughout the banking ecosystem.\n\n## Understanding the upcoming regulatory changes\n\nAcknowledging that the regulatory landscape frequently changes, this article will concentrate on key frameworks in the EU poised to shape the future of banking and financial services. These frameworks not only address current industry challenges but also set the foundation for the development of a more secure and resilient financial ecosystem.\n\nHere are several regulations that are demanding the attention of the financial services industry. \n\n### [European Cyber Resilience Act (CRA)](https://digital-strategy.ec.europa.eu/en/policies/cyber-resilience-act)  \n\nImplemented as of **January 2024,** with a grace period extending for two years, the CRA establishes a comprehensive framework to enhance cybersecurity standards for digital products and services within the EU. This regulation seeks to mitigate the risks of vulnerabilities in software and hardware by ensuring that security is integrated throughout the entire product lifecycle, promoting a proactive “shift left” approach to security. By embedding security measures from the design phase onward, the CRA aims to safeguard the digital economy and bolster consumer trust in digital services.\n\n### [Digital Operational Resilience Act (DORA)](https://www.eiopa.europa.eu/digital-operational-resilience-act-dora_en)\n\nTaking effect on **January 17, 2025**, the Digital Operations Resilience Act aims to ensure that financial institutions can withstand, respond to, and recover from all types of information and communication technology related disruptions and threats. The goal is to unify and strengthen the resilience of the financial sector across Europe. \n\n### [European Data Act](https://digital-strategy.ec.europa.eu/en/policies/data-act)  \n\nAnticipated to become applicable on **September 12, 2025**, this regulation seeks to provide clearer rules regarding data use and sharing for AI and the internet of things, or IoT, enhancing data access and fostering innovation in various sectors, including finance.\n\n## Implications for banks and financial institutions \n\nAs financial institutions adapt to these evolving regulatory frameworks, the implications are significant and far-reaching. For instance, PYMNTS reports [59% of bankers see their legacy systems as a major business challenge](https://www.pymnts.com/digital-first-banking/2024/three-quarters-of-banks-face-digital-banking-infrastructure-issues/). These challenges present obstacles in the delivery of modern services, while hindering their ability to both detect and respond to modern cyber threats. According to the [2024 IBM Data Breach Report](https://www.ibm.com/downloads/cas/1KZ3XE9D), the average cost of a data breach in the financial services sector is a staggering $6.08 million, with breaches taking an average of 258 days to identify and contain. Unfortunately for banks, the most common type of data stolen or compromised was customer personally identifiable information, or PII. This highlights the urgent need for organizations to modernize their security practices and infrastructure.\n\nHere are four ways to address this challenge.\n\n1. **Increase investment in technology:** Banks will need to significantly increase their investments in technology and infrastructure. This involves evaluating current systems and processes to ensure they align with the stringent requirements of CRA, DORA, the European Data Act, and other regulations.  \n\n2. **Heighten risk management practices:** A cultural shift will be necessary within organizations, as teams will need to prioritize risk management and resilience strategies. DORA, in particular, emphasizes not just compliance but the ability to anticipate and recover from disruptions.  \n\n3. **Enhance data governance:** Many of these new regulations will require banks to prepare for new approaches to data sharing and governance. Banks will have to rethink how data is collected, stored, and analyzed, with a strong focus on transparency, accountability, and collaboration across departments.  \n\n4. **Strengthen cybersecurity:** As cyber threats evolve, the importance of robust cybersecurity measures cannot be overstated. The CRA mandates that financial institutions implement comprehensive security protocols, requiring banks to prioritize cybersecurity investments at every phase of the software development lifecycle. \n\n## How GitLab can help   \nWith years of experience working with some of the [largest financial organizations in the world](https://about.gitlab.com/customers/all/?industry=financial-services), GitLab stands ready to support banks and other financial institutions in their compliance efforts. Our integrated suite of features empowers development teams to streamline their workflows, allowing them to concentrate on software development rather than becoming bogged down by the manual tracking and monitoring of evolving compliance regulations. \n\n**[GitLab Dedicated](https://about.gitlab.com/dedicated/)**, our fully isolated, single-tenant SaaS solution, is designed to meet the complex compliance and data residency requirements of highly regulated industries. Hosted and managed by GitLab, in your chosen cloud region, GitLab Dedicated ensures that sensitive data remains secure and compliant with local regulations. GitLab can help banks navigate these challenges effectively with:\n\n1. [Comprehensive application security and compliance features](https://about.gitlab.com/stages-devops-lifecycle/secure/)\n\n-  __Security scanning built into developer workflows:__ Many financial institutions still rely on disparate tools for security checks, which can lead to gaps in coverage and oversight. GitLab offers built-in security scanning tools that automatically identify vulnerabilities and provide remediation guidance throughout the application lifecycle. By embedding security checks into [CI/CD pipelines](https://about.gitlab.com/topics/ci-cd/cicd-pipeline/), banks can detect and resolve issues early in the development process, where they are less costly and less risky to fix, ensuring that they adhere to necessary security protocols. GitLab offers the following [security scanner types](https://docs.gitlab.com/ee/user/application_security/secure_your_application.html):\n\n      1. [Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/index.html) \n\n      2. [Dynamic Application Security Testing (DAST)](https://docs.gitlab.com/ee/user/application_security/dast/index.html)  \n      3. [Secret Detection](https://docs.gitlab.com/ee/user/application_security/secret_detection/index.html)\n\n      4. [Infrastructure as Code (IaC) Scanning](https://docs.gitlab.com/ee/user/application_security/iac_scanning/index.html)\n\n      5. [Dependency (+ License) Scanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/index.html)  \n      6. [Coverage-guided Fuzz Testing](https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing/index.html)  \n\n      7. [Web API Fuzz Testing](https://docs.gitlab.com/ee/user/application_security/api_fuzzing/)  \n\n      8. [Container Scanning](https://docs.gitlab.com/ee/user/application_security/container_scanning/index.html)  \n\n      9. [API Security Scanning](https://docs.gitlab.com/ee/user/application_security/api_security/index.html)\n\n- __Compliance and enforceable policies:__ Our platform enables [separation of duties](https://about.gitlab.com/blog/ensuring-compliance/), by allowing security and compliance teams to manage security policies independently, allowing developers to focus purely on development. This approach supports the [principle of least privilege](https://about.gitlab.com/blog/the-ultimate-guide-to-least-privilege-access-with-gitlab/), where developers access only what they need. For multinational banks or financial institutions who operate globally, GitLab’s policies and compliance dashboards assist in meeting strict geographical and regulatory requirements. These tools help maintain consistent adherence to compliance regulations, giving organizations clear visibility into their security posture across regions, industries, and regulations.\n\n- __[Software supply chain security](https://about.gitlab.com/solutions/supply-chain/):__ GitLab ensures the security of the entire build, development, and deployment environment through a comprehensive approach to software supply chain security. Our [software composition analysis (SCA)](https://about.gitlab.com/blog/reduce-supply-chain-risk-with-smarter-vulnerability-prioritization/) provides deep insights into component versions, licenses, and known vulnerabilities in dependencies which can be proactively remediated to reduce enterprise risk. This comprehensive approach also includes [software bill of materials (SBOM)](https://docs.gitlab.com/ee/user/application_security/dependency_list/) generation, ensuring transparency and compliance with industry standards. Finally, as highlighted above, GitLab provides controls to enforce the principle of least privilege to mitigate threats that compromise the software development environment itself.  \n\n2. [Robust risk management tools](https://docs.gitlab.com/ee/user/application_security/)\n\n- __Issue tracking and management:__ Within a bank, ineffective risk management can lead to overlooked vulnerabilities and inefficient mitigation strategies. GitLab’s issue tracking capabilities allow security vulnerabilities to appear alongside feature requests in the backlog, creating full visibility across teams. Sensitive issues can also be marked as confidential, so that only those who have sufficient permissions can access. This combination of transparency and controlled access supports a culture of collaboration and accountability, as development, security, and operations teams work together seamlessly on risk management. This cultural shift is crucial; rather than merely purchasing tools or one-off solutions, organizations must embed collaboration into their workflows to ensure security becomes a key part of the development process. \n\n- __[Automated testing](https://about.gitlab.com/blog/how-to-choose-the-right-security-scanning-approach/):__ A common challenge in the financial services industry is centered around the fact that homegrown solutions that were once robust processes become slow and cumbersome over time, leading to reduced agility. So much so that [Forbes](https://www.aba.com/-/media/documents/industry-insights/2023-thoughtmachine-banking-at-a-crossroads-the-threat-of-legacy-infrastructure.pdf?rev=6ce18fa56f0547e5a8c8433b50aef931) found that 60% of banking leaders consider legacy infrastructure to be the major factor keeping them from unlocking incremental growth. To compensate, the industry has shifted toward giving developers more freedom, but often at the cost of maintaining high security standards.\n\u003Cbr>\u003C/br>\n  GitLab solves this challenge by [automating testing within CI/CD pipelines](https://about.gitlab.com/topics/devops/devops-test-automation/), enabling financial institutions to maintain both speed and security. Developers can configure pipelines to fit their workflows, while security and compliance teams retain control over policies, ensuring adherence to critical security measures. By automating testing processes, GitLab helps banks remain resilient and functional, reducing the likelihood of disruptions.\n\n3. [Enhanced data governance](https://about.gitlab.com/stages-devops-lifecycle/govern/)\n\n- __Data management and compliance:__ GitLab’s data management features enable organizations to securely handle sensitive information. With embedded [audit logs](https://docs.gitlab.com/ee/user/compliance/audit_events.html), banks can track data access and changes, ensuring transparency and accountability in their data practices. These logs can show actions such as who changed the permission level of a particular user for a project, and when.\n\n- __[Collaboration tools](https://about.gitlab.com/topics/gitops/gitops-gitlab-collaboration/):__ GitLab promotes collaboration among cross-departmental teams, facilitating communication between IT, compliance, and business units. This integrated approach is essential for effective data governance, allowing banks to align their data practices with organizational goals.\n\n4. [Efficient incident reporting and response](https://docs.gitlab.com/ee/operations/incident_management/)\n\n- __[Centralized incident management](https://handbook.gitlab.com/handbook/engineering/infrastructure/incident-management/):__ GitLab provides centralized project management capabilities for logging and tracking significant incidents. This allows teams to respond quickly and effectively, ensuring that incidents are managed in a timely manner.\n\n- __[Incident response guides](https://handbook.gitlab.com/handbook/security/security-operations/sirt/sec-incident-response/):__ With GitLab, organizations can develop and maintain incident response plans within the platform. By simulating potential incidents and testing response protocols, banks can ensure preparedness and resilience in the face of unexpected challenges.\n\n5. [Documentation and audit readiness](https://docs.gitlab.com/ee/administration/compliance.html)\n\n- __Continuous compliance documentation:__ Traditionally, banks have been locked into rigid 12-month audit cycles, preparing documentation to meet stringent regulations like the Bank Secrecy Act (BSA), Automated Clearing House (ACH) rules, and Anti-Money Laundering (AML) requirements. However, as the pace and complexity of threats grow, the financial industry is shifting from reactive, periodic audits to a proactive, [continuous compliance model](https://about.gitlab.com/blog/meet-regulatory-standards-with-gitlab/). With GitLab, teams know exactly where they stand at any given moment, leveraging real-time compliance data to their advantage. This continuous insight empowers teams to address issues as they arise, rather than waiting for an audit, creating a more agile and resilient compliance posture.\n\n- **Customizable reporting:** With GitLab’s customizable reporting features, organizations can generate detailed reports that showcase compliance violations based on severity levels, violation types, and merge request titles. These reports provide valuable insights for both internal stakeholders and external parties, ensuring transparency and accountability.\n\n## Connect with GitLab today\n\nAs banks and financial institutions embrace these regulatory changes, GitLab not only provides the technology necessary to ensure compliance, but also fosters a culture of continuous improvement. This proactive approach allows financial institutions to release software with confidence, knowing they have the systems in place to mitigate risks and respond quickly to incidents.\n\nGitLab’s commitment to supporting the financial sector through these transitions ensures that organizations are not only compliant but also resilient and prepared for the challenges ahead. Together, we can build a safer and more secure financial future. \n\n> **[Reach out](https://about.gitlab.com/solutions/finance/) to learn more about how we can help meet your regulatory challenges.**\n\n## Read more\n\n- [What the Digital Operational Resilience Act means for banks](https://about.gitlab.com/blog/what-the-digital-operational-resilience-act-means-for-banks/)\n- [Meet regulatory standards with GitLab security and compliance](https://about.gitlab.com/blog/meet-regulatory-standards-with-gitlab/)\n- [How to ensure separation of duties and enforce compliance with GitLab](https://about.gitlab.com/blog/ensuring-compliance/)",[571,9,496,694],{"slug":2184,"featured":6,"template":698},"gitlab-supports-banks-in-navigating-regulatory-challenges","content:en-us:blog:gitlab-supports-banks-in-navigating-regulatory-challenges.yml","Gitlab Supports Banks In Navigating Regulatory Challenges","en-us/blog/gitlab-supports-banks-in-navigating-regulatory-challenges.yml","en-us/blog/gitlab-supports-banks-in-navigating-regulatory-challenges",{"_path":2190,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2191,"content":2196,"config":2201,"_id":2203,"_type":14,"title":2204,"_source":16,"_file":2205,"_stem":2206,"_extension":19},"/en-us/blog/gitlab-survey-highlights-wins-challenges-as-orgs-adopt-devsecops",{"title":2192,"description":2193,"ogTitle":2192,"ogDescription":2193,"noIndex":6,"ogImage":942,"ogUrl":2194,"ogSiteName":686,"ogType":687,"canonicalUrls":2194,"schema":2195},"GitLab survey highlights wins, challenges as orgs adopt DevSecOps","This year’s survey findings show that DevSecOps principles, together with a DevSecOps platform, help organizations ship more secure software, faster.","https://about.gitlab.com/blog/gitlab-survey-highlights-wins-challenges-as-orgs-adopt-devsecops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab survey highlights wins, challenges as orgs adopt DevSecOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David DeSanto, Chief Product Officer, GitLab\"}],\n        \"datePublished\": \"2023-04-20\",\n      }",{"title":2192,"description":2193,"authors":2197,"heroImage":942,"date":2198,"body":2199,"category":10,"tags":2200},[1905],"2023-04-20","\nSecurity is everyone’s responsibility. And when everyone works together and has access to the same tools, you don’t have to sacrifice performance, efficiency, or security. That's the message from the respondents of our recent survey of software developers, IT operations, and IT security professionals worldwide. Where there is unity among Development, Security, and Operations in the common goal of securing the software supply chain, there is success.\n\nOur first report from the survey, [Security Without Sacrifices](https://about.gitlab.com/developer-survey/), focuses on this throughline and illuminates where [DevSecOps](/topics/devsecops/) professionals feel positive about their efforts to secure the software development lifecycle and where they feel work still needs to be done. While the results are not surprising — they align with what I hear from customers every day — they reinforce GitLab’s belief that DevSecOps principles, coupled with a DevSecOps platform, help organizations ship more secure software, faster.\n\nFor instance, in last year’s report, a majority of development, security, and operations professionals said they felt individually responsible for security. This year, 53% of respondents said they are responsible for application security *as part of a larger team*. And 71% of security professionals said at least a quarter of all security vulnerabilities are being spotted by developers, up from 53% in 2022.\n\nWhat this tells us is that security is indeed making its way deep into the software development lifecycle and as more innovation is introduced into the daily workflow, including AI-assisted capabilities, the benefits are tangible.\n\nHere’s what the report findings suggest organizations should keep in mind so they can get the most out of DevSecOps.\n\n## AI is now inseparable from DevSecOps\nFor the past several years, we’ve seen AI become more and more established in software development workflows. In this year’s report, nearly two-thirds (65%) of developers said they are using AI in testing efforts or will be in the next three years. We also saw an uptick this year in the number of developers who are using AI to check code.\n\nAI represents a tectonic shift in the market that will have profound effects on how organizations deliver value to customers. To take full advantage of AI, it will be critical for organizations to apply AI-assisted workflows across the entire software development lifecycle and make them available to all personas — not just developers but everyone involved in the delivery of software value, from security and compliance teams to product development and marketing.\n\n## Security toolchain expansion is unsustainable\nThis year’s report showed that toolchain sprawl may be a bigger concern for security professionals than for the rest of the team; 57% of security respondents said they use six or more tools, compared to 48% of developers and 50% of operations professionals. We’re also seeing signs that security professionals are using _more_ tools than in past years. This is in line with what security practitioners tell me: They use different tools for each security function, including composition analysis, fuzzing, DAST, and dependency scanning.\n\nThe rise of DevOps and DevSecOps is making it easier for software development teams to consolidate tools, but the increased pressure around software supply chain security means this trend is not holding for security as it is for other roles. Security practitioners select the tools that get the job done and the tools they’re most comfortable with, but as security budgets tighten, that’s no longer going to be a sustainable strategy. We should expect to see a bigger push to consolidate security toolchains over the next several years.\n\n## Efficiency and security cannot be mutually exclusive\nThe first wave of budget tightening seems to be here already — 85% of the security professionals we surveyed told us they have the same or less budget this year than they did in 2022, and security professionals were also more likely than both developers and operations professionals to cite macroeconomic forces as a primary factor driving DevOps/DevSecOps to scale at their organizations. In this environment, organizations (and security teams) need to do more with less.\n\nFor many of the organizations I’ve talked to, tighter budgets mean more than just cutting costs. Organizations need to ensure they’re getting a swifter return on their DevSecOps investments. That return on investment could look like increased efficiency, translating into accelerated value delivery for customers, faster innovation, and more revenue. Or it could mean incorporating security and compliance tools earlier in the development lifecycle, reducing risk. Ideally, it’s all of the above. As organizations seek ways to stay ahead of the competition, security and efficiency are both non-negotiable.\n\n## A platform approach: The winning formula for DevSecOps\nHow can organizations foster collaboration, reduce toolchain friction, and boost efficiency without sacrificing security? A platform that puts DevSecOps methodologies into practice. This year’s respondents identified security and efficiency as the top two benefits of adopting a DevSecOps platform, ahead of automation, cost savings, and collaboration.\n\nA DevSecOps platform enables teams to collaborate in a single application, shortening cycle times, reducing risks, and accelerating everyone’s workflows. We see proof points in this year’s data: Security professionals who use a DevSecOps platform were significantly more likely than those who don’t use a platform to say developers catch more security vulnerabilities and had a higher opinion of their organization’s security efforts.\n\nIt has become important for organizations to foster collaboration and engagement to keep development, security, and operations teams happy.\n\n## Explore this year’s report\nRead the first report in our 2023 Global DevSecOps Report Series, [Security Without Sacrifices](https://about.gitlab.com/developer-survey/), and stay tuned for more reports on the data in the coming months.\n",[952,9,694,717],{"slug":2202,"featured":6,"template":698},"gitlab-survey-highlights-wins-challenges-as-orgs-adopt-devsecops","content:en-us:blog:gitlab-survey-highlights-wins-challenges-as-orgs-adopt-devsecops.yml","Gitlab Survey Highlights Wins Challenges As Orgs Adopt Devsecops","en-us/blog/gitlab-survey-highlights-wins-challenges-as-orgs-adopt-devsecops.yml","en-us/blog/gitlab-survey-highlights-wins-challenges-as-orgs-adopt-devsecops",{"_path":2208,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2209,"content":2212,"config":2220,"_id":2222,"_type":14,"title":2223,"_source":16,"_file":2224,"_stem":2225,"_extension":19},"/en-us/blog/gitlab-ultimate-for-ibm-z-modern-devsecops-for-mainframes",{"noIndex":6,"description":2210,"title":2211},"A new offering from GitLab and IBM bridges mainframe and cloud-native development with seamless integration, CI/CD runner support, end-to-end visibility, and cost efficiency. ","GitLab Ultimate for IBM Z: Modern DevSecOps for mainframes",{"title":2211,"description":2210,"body":2213,"category":848,"tags":2214,"authors":2215,"heroImage":2218,"date":2219},"GitLab and IBM have partnered to solve a fundamental disconnect in enterprise development: enabling mainframe developers to work with the same modern tools, workflows, and collaboration features as their distributed counterparts. GitLab Ultimate for IBM Z, a GitLab-certified, integrated DevSecOps solution tailored for the mainframe environment, does just that — allowing organizations to modernize their mainframe development workflows by facilitating a seamless migration from outdated legacy library managers. With CI/CD pipelines running natively on IBM z/OS, customers experience accelerated innovation and reduced operational costs.\n\n## Challenges of today's mainframe development\n\nEnterprise organizations that use IBM Z systems for mission-critical workloads face challenges that conventional DevSecOps tools aren’t equipped to address. Cloud-native teams benefit from modern [CI/CD](https://about.gitlab.com/topics/ci-cd/) pipelines, collaborative development, and automated testing. In contrast, mainframe teams are often left behind — stuck with outdated tools that lead to costly inefficiencies and operational silos.\n\nTeams often resort to workarounds, such as SSH connections and manual file transfers, which create security vulnerabilities and audit difficulties. When compliance requirements are stringent, these improvised solutions become unacceptable risks. Meanwhile, organizations maintain expensive parallel toolchains, with legacy mainframe development tools carrying premium licensing costs while delivering limited functionality compared to modern alternatives.\n\nThis fragmentation creates two problems: slower delivery cycles and difficulty attracting developers who expect modern development experiences.\n\n> **\"GitLab Ultimate for IBM Z represents an important step in addressing a long-standing industry challenge. IDC research shows that mainframe developers often work with legacy tooling that contributes to delivery inefficiencies and makes it harder to attract new talent. With this offering, modern DevSecOps capabilities and unified workflows are brought directly to the mainframe. This empowers developers to work more collaboratively and efficiently, while helping organizations accelerate innovation and integrate mainframe development into broader digital transformation strategies.\"** - Katie Norton, Research Manager, DevSecOps and Software Supply Chain Security at IDC\n\n## Unified development environments\n\nTrue modernization means more than just updating mainframe development. It means creating a unified platform where mainframe, cloud-native, web, and mobile development teams collaborate seamlessly.\n\nGitLab Ultimate for IBM Z enables developers to use consistent workflows whether they're deploying to z/OS, cloud, or on-premises infrastructure — knowledge transfers between teams instead of staying siloed. Organizations can modernize incrementally without business disruption, as legacy systems continue operating while teams adopt modern practices at their own pace.\n\nAs organizations pursue hybrid cloud strategies, GitLab provides the foundation for applications that span mainframe and cloud-native environments.\n\n## What is GitLab Ultimate for IBM Z?\n\nGitLab Ultimate for IBM Z delivers native z/OS Runner support, enabling seamless CI/CD pipeline execution directly on your mainframe infrastructure. This GitLab-certified solution helps eliminate the need for complex workarounds while maintaining the security and reliability your enterprise applications demand.\n\nThe combination of GitLab's comprehensive DevSecOps platform with IBM's deep mainframe expertise creates something unique in the market: a certified solution that provides a true bridge between enterprise legacy systems and cloud-native innovation.\n\n## GitLab Ultimate for IBM Z capabilities\n\nGitLab Ultimate for IBM Z provides enterprise teams with the tools they need to modernize mainframe development while preserving critical business systems.\n\n**Native z/OS Runner support** helps eliminate security risks and scalability bottlenecks associated with remote connections, while accelerating delivery through CI/CD pipelines that execute directly where your mainframe code resides.\n\n**Unified Source Code Management** modernizes your toolchain by replacing expensive legacy library managers with GitLab's searchable, version-controlled repository system, helping reduce licensing costs and maintenance overhead.\n\n**Seamless integration** with IBM Developer for z/OS Enterprise Edition (IDzEE) delivers faster software releases through dependency-based builds, automated code scanning, and comprehensive debugging tools within familiar developer environments, enhancing both quality and security.\n\n**End-to-end visibility** across mainframe and distributed environments provides comprehensive project management from planning to production, enabling automated DevOps workflows that help retain talent through modern, next-generation development tools.\n\n## Modernize your mainframe development environment today\n\nGitLab Ultimate for IBM Z is available now for organizations ready to transform their mainframe development experience. To learn more, visit the [GitLab and IBM partnership page](https://about.gitlab.com/partners/technology-partners/ibm/).",[284,848,109,9],[2216,2217],"Mike Flouton","Andy Bradfield","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750440008/myqt5vcjlffh8sszw507.png","2025-06-23",{"featured":91,"template":698,"slug":2221},"gitlab-ultimate-for-ibm-z-modern-devsecops-for-mainframes","content:en-us:blog:gitlab-ultimate-for-ibm-z-modern-devsecops-for-mainframes.yml","Gitlab Ultimate For Ibm Z Modern Devsecops For Mainframes","en-us/blog/gitlab-ultimate-for-ibm-z-modern-devsecops-for-mainframes.yml","en-us/blog/gitlab-ultimate-for-ibm-z-modern-devsecops-for-mainframes",{"_path":2227,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2228,"content":2233,"config":2238,"_id":2240,"_type":14,"title":2241,"_source":16,"_file":2242,"_stem":2243,"_extension":19},"/en-us/blog/gitlab-uses-anthropic-for-smart-safe-ai-assisted-code-generation",{"title":2229,"description":2230,"ogTitle":2229,"ogDescription":2230,"noIndex":6,"ogImage":1860,"ogUrl":2231,"ogSiteName":686,"ogType":687,"canonicalUrls":2231,"schema":2232},"GitLab uses Anthropic for smart, safe AI-assisted code generation","Anthropic’s Claude AI model supports the delivery of helpful, trusted code in GitLab Duo Code Suggestions.","https://about.gitlab.com/blog/gitlab-uses-anthropic-for-smart-safe-ai-assisted-code-generation","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab uses Anthropic for smart, safe AI-assisted code generation\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kevin Chu\"}],\n        \"datePublished\": \"2024-01-16\",\n      }",{"title":2229,"description":2230,"authors":2234,"heroImage":1860,"date":2097,"body":2236,"category":781,"tags":2237},[2235],"Kevin Chu","GitLab recently launched GitLab Duo Code Suggestions into general availability. Code Suggestions includes the ability to generate algorithms or code blocks directly within the developer's IDE, a capability that uses [Anthropic's](https://www.anthropic.com/) generative AI model, [Claude](https://www.anthropic.com/index/claude-2-1). Integrated into the GitLab Duo portfolio of AI-assisted features, Claude is compatible with GitLab’s principles of [transparency and privacy](https://about.gitlab.com/the-source/ai/building-a-transparency-first-ai-strategy-7-questions-to-ask-your-devops/) by design and provides a high-integrity foundation for code generation.\n\nIn this post, you'll learn the advantages of code generation and how GitLab, together with Anthropic, is leveraging AI to responsibly boost developer productivity.\n\n## How AI-assisted code generation works\n\nCode Suggestions is incredibly useful as a coding companion that shows the suggestions as a developer types. It helps save developer time and keystrokes, reducing the effort for rote tasks and giving developers time back in their day. But what if a developer wants to do even more with generative AI?\n\nEnter code generation.\n\nImagine needing to write a new complex function based on an unfamiliar algorithm, or write a large amount of boilerplate code. Instead of struggling through these tasks with gritted teeth, code generation allows developers to simply define what they want to do in comments or multi-line comment blocks, and then Code Suggestions generates the code from there.\n\nHere is an example of Code Suggestions generating a JavaScript function that calculates the Levenshtein distance, a string metric useful for comparing the difference between two sequences:\n\n\u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752175962/Blog/lkrk16unp4dcy3c4zwvw.gif\" alt=\"Code Suggestions generating JavaScript function\" width=\"100%\" height=\"auto\">\n\nHere is another example showing a multi-line comment in Python. We want Code Suggestions to generate a Tornado Web Server that does three things: log in, run a scan, and review the results. By providing the specific instructions, including details such as the framework and the components to use,, Code Suggestions was able to generate a Tornado App, despite this author being unfamiliar with Tornado.\n\n\u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752175967/Blog/pxcdppnpzwfhgopxh999.gif\" alt=\"Code Suggestions generating Tornado app\" width=\"100%\" height=\"auto\">\n\nSafety through focus and trustworthiness\nDevelopers expect AI coding assistants to not only be helpful, but also accurate and safe. The system should generate precisely what is asked for while limiting deviation and [hallucination](https://www.ibm.com/topics/ai-hallucinations). Customers want assurances that AI-generated code can be trusted.\n\nThroughout GitLab's evaluation of certain code generation models, Claude stood out for its ability to mitigate distracting, unsafe, or deceptive behaviors. Claude also demonstrated consistent and accurate code generation throughout our testing.\n\nGitLab's use of Anthropic's Claude enables Code Suggestions to balance automation with trust. Code Suggestions helps users become more efficient without sacrificing reliability — a win for augmented development.\n\n## What’s next\n\nReady to experience the future of code generation? Start your [free trial of GitLab Duo](https://about.gitlab.com/gitlab-duo/) today and unlock the power of AI-assisted development!",[717,233,9,1299],{"slug":2239,"featured":91,"template":698},"gitlab-uses-anthropic-for-smart-safe-ai-assisted-code-generation","content:en-us:blog:gitlab-uses-anthropic-for-smart-safe-ai-assisted-code-generation.yml","Gitlab Uses Anthropic For Smart Safe Ai Assisted Code Generation","en-us/blog/gitlab-uses-anthropic-for-smart-safe-ai-assisted-code-generation.yml","en-us/blog/gitlab-uses-anthropic-for-smart-safe-ai-assisted-code-generation",{"_path":2245,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2246,"content":2251,"config":2256,"_id":2258,"_type":14,"title":2259,"_source":16,"_file":2260,"_stem":2261,"_extension":19},"/en-us/blog/gitlab-visual-studio-extension",{"title":2247,"description":2248,"ogTitle":2247,"ogDescription":2248,"noIndex":6,"ogImage":839,"ogUrl":2249,"ogSiteName":686,"ogType":687,"canonicalUrls":2249,"schema":2250},"GitLab for Visual Studio, including code suggestions, available in Beta","GitLab for Visual Studio is now available in Beta, bringing GitLab Duo code suggestions to Visual Studio.","https://about.gitlab.com/blog/gitlab-visual-studio-extension","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab for Visual Studio, including code suggestions, available in Beta\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kai Armstrong\"}],\n        \"datePublished\": \"2023-06-29\",\n      }",{"title":2247,"description":2248,"authors":2252,"heroImage":839,"date":2253,"body":2254,"category":781,"tags":2255},[1592],"2023-06-29","\n\n\u003Ci>This blog is the latest post in an ongoing series about GitLab's journey to \u003Ca href=\"/blog/ai-ml-in-devsecops-series/\">build and integrate AI/ML into our DevSecOps platform\u003C/a>. The first blog post can be found \u003Ca href=\"/blog/what-the-ml-ai/\">here\u003C/a>. Throughout the series, we'll feature blogs from our product, engineering, and UX teams to showcase how we're infusing AI/ML into GitLab.\u003C/i>\n\nIn June, we shared our plans to [extend code suggestions](/blog/extending-code-suggestions/) to more IDEs, thereby continuing to enhance developer productivity. Over the past several weeks, we've been iterating quickly and we can share that GitLab for Visual Studio is available ([in Beta](https://docs.gitlab.com/ee/policy/experiment-beta-support.html#beta)) from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=GitLab.GitLabExtensionForVisualStudio).\n\nThe GitLab for Visual Studio extension supports [GitLab Duo](https://about.gitlab.com/gitlab-duo/) code suggestions for both [GitLab SaaS](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-on-gitlab-saas) and [GitLab self-managed](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-on-self-managed-gitlab).\n\nDownload it and let us know what you think and any issues you're having in our [feedback issue](https://gitlab.com/gitlab-org/editor-extensions/gitlab-visual-studio-extension/-/issues/38).\n\n## Getting started\nTo get started with the extension, download it from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=GitLab.GitLabExtensionForVisualStudio). After the extension is downloaded and installed, you can follow our [setup instructions](https://gitlab.com/gitlab-org/editor-extensions/gitlab-visual-studio-extension/-/blob/main/README.md#setup) to get it configured.\n\n![GitLab for Visual Studio setup](https://about.gitlab.com/images/blogimages/gitlab-visual-studio-extension-setup.png)\n\n## Using the extension\nOnce you've set up the extension, make sure things are configured properly and authentication is working by checking the status bar icon.\n\n![GitLab for Visual Studio status bar icon](https://about.gitlab.com/images/blogimages/gitlab-visual-studio-extension-status-bar-icon.png)\n\nIf everything looks good, you're ready to start receiving code suggestions as you work. Just start typing and GitLab Duo will automatically provide you suggestions inline. You can press \u003Ckbd>Tab\u003C/kbd> to accept the suggestions or just keep typing to receive new suggestions.\n\n![GitLab for Visual Studio suggestions](https://about.gitlab.com/images/blogimages/gitlab-visual-studio-extension-suggestions.gif)\n\n## Iterating on AI/ML features\nWhile this brings us one step closer to reaching developers working in Visual Studio, we still have our eyes on the [JetBrains IDEs](https://gitlab.com/gitlab-org/editor-extensions/gitlab-jetbrains-plugin) as well as a native integration for [Neovim](https://gitlab.com/gitlab-org/editor-extensions/gitlab.vim). You can track these projects and stay tuned for future announcements regarding their availability.\n\nWe're also working on a [GitLab Language Server for code suggestions](https://gitlab.com/gitlab-org/editor-extensions/gitlab-language-server-for-code-suggestions). This allows us to not only standardize and iterate faster on our IDE extensions, but for users of IDEs and Editors to use GitLab Duo code suggestions even if we're not officially providing an extension. We look forward to providing more documentation and working with the community on this project in the future.\n\nThese efforts are just the start of how we're bringing GitLab Duo capabilities throughout the software development lifecycle to help GitLab users become more efficient and effective at their jobs. We are [looking across the software development lifecycle](/blog/what-the-ml-ai/) for painful and time-consuming tasks that are ideal for AI-assisted features. We'll continue to share these demos throughout this blog series.\n\nInterested in using these AI-generated features? [Join our waitlist](https://forms.gle/9eeUkPJauKsbLaoz5) and share your ideas.\n\nContinue reading our \"[AI/ML in DevSecOps](/blog/ai-ml-in-devsecops-series/)\" series.\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[9,848,719,717],{"slug":2257,"featured":6,"template":698},"gitlab-visual-studio-extension","content:en-us:blog:gitlab-visual-studio-extension.yml","Gitlab Visual Studio Extension","en-us/blog/gitlab-visual-studio-extension.yml","en-us/blog/gitlab-visual-studio-extension",{"_path":2263,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2264,"content":2269,"config":2274,"_id":2276,"_type":14,"title":2277,"_source":16,"_file":2278,"_stem":2279,"_extension":19},"/en-us/blog/gitlabs-maven-dependency-proxy-is-available-in-beta",{"title":2265,"description":2266,"ogTitle":2265,"ogDescription":2266,"noIndex":6,"ogImage":942,"ogUrl":2267,"ogSiteName":686,"ogType":687,"canonicalUrls":2267,"schema":2268},"GitLab's Maven dependency proxy is available in Beta","Enterprises can use new package registry feature to consolidate artifact management on GitLab, increasing the efficiency and speed of CI/CD pipelines.","https://about.gitlab.com/blog/gitlabs-maven-dependency-proxy-is-available-in-beta","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"GitLab's Maven dependency proxy is available in Beta\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Tim Rizzi\"}],\n        \"datePublished\": \"2023-12-11\",\n      }",{"title":2265,"description":2266,"authors":2270,"heroImage":942,"date":2271,"body":2272,"category":994,"tags":2273},[2096],"2023-12-11","GitLab is introducing the Maven dependency proxy, a new feature that will enable enterprises to consolidate on the DevSecOps platform for artifact management. The Maven dependency proxy, [available in Beta](https://gitlab.com/groups/gitlab-org/-/epics/3610), enables larger organizations to be more efficient by expanding the functionality of GitLab's package registry. The new feature can make pipelines faster and more reliable, and can reduce the cost of data transfer since over time most packages will be pulled from the cache.\n\n## How the Maven dependency proxy works\n\nA typical software project relies on a variety of dependencies, which we call packages. Packages can be internally built and maintained, or sourced from a public repository. Based on our user research, we’ve learned that most projects use a 50/50 mix of public vs. private packages. When installing packages, the order in which they are found and downloaded is very important, as downloading or using an incorrect package or version of a package can introduce breaking changes and security vulnerabilities into their pipelines.\n\nThe Maven dependency proxy gives users the ability to add or configure one external Java repository. Once added, when a user tries to install a Java package using their project-level endpoint, GitLab will first look for the package in the project and if it's not found, will attempt to pull the package from the external repository.\n\nWhen a package is pulled from the external repository, it will be imported into the GitLab project so that the next time that particular package/version is pulled it's pulled from GitLab and not the external repository. If the external repository is having connectivity issues and the package is present in the dependency proxy, then pulling that package will work. This will make your pipelines faster and more reliable.\n\nIf the package changes in the external repository — for example, a user deletes a version and publishes a new one with different files — the dependency proxy will detect that and invalidate the package in GitLab to pull the \"newer\" one. This will ensure that the correct packages are downloaded and help to reduce security vulnerabilities. \nIf the package is not found in their GitLab project or the external repository, GitLab will return an error.\n\nHere are more details of the Maven dependency proxy:\n- This feature and all future dependency proxy formats will be in the Premium tier.\n- Project owners will be able to configure this feature via a project's settings (API or UI).\n- We will support external repositories that require authentication, such as Artifactory or Sonatype.\n\n## A fit for the enterprise\n\nEnterprise organizations that need to consolidate on GitLab and move away from Artifactory or Sonatype can make use of the new Maven dependency proxy. Virtual registries allow you to publish, proxy, and cache multiple package repositories behind a single, logical URL. \n\nThe Maven dependency proxy is the MVC of a set of features that will help enterprise organizations sunset their existing artifact management vendors, such as Artifactory or Sonatype Nexus, to help reduce costs and improve the developer user experience.\n\n#### Roadmap\n- [Finish the Maven dependency proxy](https://gitlab.com/groups/gitlab-org/-/epics/3610) (Milestone 16.7)\n- [npm dependency proxy](https://gitlab.com/groups/gitlab-org/-/epics/3608) \n- [Make the dependency proxy for containers work generically with any container registry](https://gitlab.com/groups/gitlab-org/-/epics/6061)\n- [PyPI dependency proxy](https://gitlab.com/groups/gitlab-org/-/epics/3612)\n- [NuGet dependency proxy](https://gitlab.com/groups/gitlab-org/-/epics/3611)\n\n## How we will measure success\n\nWe will start to measure success by tracking adoption by tier with the following metrics:\n\n- Number of packages pulled through the dependency proxy\n- The hit ratio (packages pulled from the cache vs. upstream repository)\n- Number of users that pulled a package through the dependency proxy\n\n## How to get started\n\nIn the video below, you can see a short demo of the Maven dependency proxy in action.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/9NPTXObsSrE?si=MFWg5C9j5a97LBeE\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n### Prerequisites\n\n- As of the time of writing this, the feature is behind a feature flag.\n- The settings for your project must be updated using [GraphQL](https://gitlab.com/-/graphql-explorer).\n\n> Join the Beta program by adding a comment to [this epic](https://gitlab.com/groups/gitlab-org/-/epics/3610). Note: The feature is planned to go to general availability in Version 16.7 or 16.8.\n",[994,109,1039,9],{"slug":2275,"featured":91,"template":698},"gitlabs-maven-dependency-proxy-is-available-in-beta","content:en-us:blog:gitlabs-maven-dependency-proxy-is-available-in-beta.yml","Gitlabs Maven Dependency Proxy Is Available In Beta","en-us/blog/gitlabs-maven-dependency-proxy-is-available-in-beta.yml","en-us/blog/gitlabs-maven-dependency-proxy-is-available-in-beta",{"_path":2281,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2282,"content":2288,"config":2295,"_id":2297,"_type":14,"title":2298,"_source":16,"_file":2299,"_stem":2300,"_extension":19},"/en-us/blog/happy-birthday-secure-by-design",{"title":2283,"description":2284,"ogTitle":2283,"ogDescription":2284,"noIndex":6,"ogImage":2285,"ogUrl":2286,"ogSiteName":686,"ogType":687,"canonicalUrls":2286,"schema":2287},"Happy birthday, Secure by Design!","The U.S. government's initiative to ensure greater security in software products turns one. Find out what GitLab has done to align with this critical effort.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664530/Blog/Hero%20Images/AdobeStock_282096522.jpg","https://about.gitlab.com/blog/happy-birthday-secure-by-design","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Happy birthday, Secure by Design!\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Joel Krooswyk\"}],\n        \"datePublished\": \"2024-04-30\",\n      }",{"title":2283,"description":2284,"authors":2289,"heroImage":2285,"date":2291,"body":2292,"category":694,"tags":2293},[2290],"Joel Krooswyk","2024-04-30","When the Cybersecurity and Infrastructure Security Agency (CISA) first published its [Secure by Design](https://www.cisa.gov/securebydesign) software protection initiative on April 13, 2023, the industry paid close attention. The initiative urges all software manufacturers to take the steps necessary to ensure that the products they ship are, in fact, secure by design. At GitLab, we quickly assessed our alignment with the initiative and over the past year have continued to innovate in accordance with CISA's guidelines.\n\nCISA's Secure by Design introduced three software security principles:\n\n1. Take ownership of customer security outcomes.\n\n2. Embrace radical transparency and accountability.\n\n3. Build organizational structure and leadership to achieve these goals.\n\n## A year of government guidance  \n\nThe U.S. government has produced significant guidance throughout the past year that reflects the Secure by Design theme. Here are just a few highlights:\n\n* August 2023: ONCD in partnership with several other agencies kicked off the [OS3i Initiative](https://www.whitehouse.gov/oncd/briefing-room/2023/08/10/fact-sheet-office-of-the-national-cyber-director-requests-public-comment-on-open-source-software-security-and-memory-safe-programming-languages/) to prioritize focus areas related to open source software security.\n* August 2023: NIST produced [SP 800-204D ](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-204D.pdf)to provide practical software supply chain security strategies for DevSecOps CI/CD pipelines.\n* October 2023: CISA released a second iteration of the [Secure by Design](https://www.cisa.gov/sites/default/files/2023-10/SecureByDesign_1025_508c.pdf) document.\n* October 2023: The [AI Executive Order](https://www.whitehouse.gov/briefing-room/statements-releases/2023/10/30/fact-sheet-president-biden-issues-executive-order-on-safe-secure-and-trustworthy-artificial-intelligence/) was issued by the Biden Administration. Since then, AI engagement guidelines have been produced by most government agencies.\n* December 2023: CISA produced [Memory Safe Roadmap guidance](https://www.cisa.gov/sites/default/files/2023-12/The-Case-for-Memory-Safe-Roadmaps-508c.pdf).\n* February 2024: NIST released the [CyberSecurity Framework 2.0](https://www.nist.gov/news-events/news/2024/02/nist-releases-version-20-landmark-cybersecurity-framework).\n* March 2024: CISA and OMB published the [Secure Software Development Attestation Form](https://www.cisa.gov/secure-software-attestation-form) and opened a [repository](https://www.cisa.gov/news-events/news/cisa-publishes-repository-software-attestation-and-artifacts) for collection of the attestations.\n\n## How GitLab has evolved with the Secure by Design initiative\n\nGitLab has also continued to grow in alignment with the Secure by Design initiative over the past year. Here are some examples.\n\n### GitLab signed the Secure by Design Pledge\n\nGitLab is proud to have signed the CISA [Secure by Design Pledge](https://www.cisa.gov/securebydesign/pledge).\n\n\"The Secure by Design concepts are well-aligned with GitLab's core values. As the most comprehensive AI-powered DevSecOps platform, GitLab offers its unwavering support towards CISA’s efforts to instill a Secure by Design mindset in software manufacturers. GitLab is proud to make the Secure by Design Pledge, and we firmly believe these efforts will help us enable everyone to innovate and succeed on a safe, secure, and trusted DevSecOps platform,\" said GitLab Chief Information Security Officer Josh Lemos.\n\n### \"Secure by default\" practices\n\nConfiguring and securing installations and users can be a challenge. GitLab developed granular user access with [custom user roles](https://docs.gitlab.com/ee/user/custom_roles.html) and [customizable permissions](https://docs.gitlab.com/ee/user/custom_roles/abilities.html). Management of [tokens](https://docs.gitlab.com/ee/security/token_overview.html), [API service accounts](https://docs.gitlab.com/ee/user/profile/service_accounts.html), and [credentials](https://docs.gitlab.com/ee/administration/credentials_inventory.html) have been in focus with continuous improvements and more rigorous authentication security capabilities throughout the year. \n\n### Secure software development practices\n\nWith every release, GitLab has incrementally enhanced scanning accuracy, coverage, and capabilities across our entire suite of security analyzers.\n\n- Some [scan results are presented in developer context](https://docs.gitlab.com/ee/user/application_security/#gitlab-workflow-extension-for-vs-code) (like the IDE) simplify workflows and shift security further left.\n\n- [CI/CD pipeline](https://docs.gitlab.com/ee/ci/pipelines/) capabilities, which have been expanded and simplified, ensure better functionality while also bolstering security and compliance with enforcement and policies.\n\n- [Vulnerability management](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/) provides better views at scale, improved filtering, and more options to take action against vulnerability findings.\n\n- [Artifact attestations](https://docs.gitlab.com/ee/ci/yaml/signing_examples.html) provide a trustworthy authentication of each software artifact.\n\n### Secure business practices\n\nEach GitLab release demonstrated increased focus on compliance. Enhanced [auditing](https://docs.gitlab.com/ee/administration/audit_event_reports.html) and [event streaming](https://docs.gitlab.com/ee/administration/audit_event_streaming/) provide accountability across the entire SDLC. Compliance teams are now better equipped to proactively align to requirements, thanks to increased [policy management](https://docs.gitlab.com/ee/administration/compliance.html#policy-management), [workflow automation](https://docs.gitlab.com/ee/administration/compliance.html#compliant-workflow-automation), visibility via [compliance reporting](https://docs.gitlab.com/ee/user/compliance/compliance_center/), and [exportability of data](https://docs.gitlab.com/ee/user/compliance/compliance_center/compliance_standards_adherence_dashboard.html#export-compliance-standards-adherence-report-for-projects-in-a-group). \n\n## GitLab's Secure by Design features\n\nHere are some of the features and capabilities that align with Secure by Design.\n\n### SBOMs\n\nGitLab’s dynamic [software bill of materials](https://about.gitlab.com/blog/the-ultimate-guide-to-sboms/) focus improved SBOM generation while adding third-party SBOM intake capabilities. This also led to the ability to combine SBOMs, as well as to provide full attestation for standardized SBOM artifacts. Enhancements such as cross-project dependency visibility as well as dependency graphs enabled a better view of SBOM risk at scale. Continuous vulnerability scanning for SBOMs was also added during the past year, providing continuous insights for emergent risks for projects that are not under continuous development – no CI/CD pipeline required.\n\n### Vulnerability management\n\nNotable improvements can be seen in vulnerability management as GitLab product updates increased visibility to vulnerabilities at scale, added flexibility to [filtering](https://docs.gitlab.com/ee/user/application_security/vulnerability_report/#group-vulnerabilities), and added [remediation detail](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/#vulnerability-dismissal-reasons) options. With [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our AI-powered suite of features, AI-assisted vulnerability remediation is taking a dramatic step forward.\n\n### AI-powered workflows\n\nSpeaking of AI, we deployed many [GitLab Duo features](https://about.gitlab.com/gitlab-duo/#features) during the past year that can help expedite Secure by Design execution, including:\n\n1. Code Suggestions - Use natural language processing to generate new code.\n2. Code Explanation - Discover what that uncommented code does in order to  properly maintain code bases and provide contextually aware product updates.\n3. Code Refactoring - Refactor legacy code bases into new libraries, functions, or memory-safe languages.\n4. Vulnerability Explanation - Understand the impact of a vulnerability and why it is creating risk to enable more accurate and thorough remediation.\n5. Vulnerability Resolution - Automatically resolve vulnerabilities to save significant amounts of time.\n6. Root Cause Analysis - Determine the root cause for a pipeline failure and failed CI/CD build.\n\n### Radical transparency\n\nGitLab continues to embrace its Transparency value by creating the [GitLab Trust Center](https://trust.gitlab.com/) and the [GitLab AI Transparency Center](https://about.gitlab.com/ai-transparency-center/). These public-facing pages provide radical transparency to GitLab's values, ethics, feature details, and compliance statements – including a [NIST Secure Software Development Framework](https://csrc.nist.gov/projects/ssdf) self-attestation letter.\n\n## What's next?\n\nAs Secure by Design enters its second year, we look forward to additional guidance and initiatives from CISA and other government agencies that will provide users around the world with more securely developed software.\n\n> Want to test-drive GitLab's security features? [Try GitLab Ultimate for free](https://about.gitlab.com/free-trial/devsecops/).",[694,496,9,2294,186],"zero trust",{"slug":2296,"featured":91,"template":698},"happy-birthday-secure-by-design","content:en-us:blog:happy-birthday-secure-by-design.yml","Happy Birthday Secure By Design","en-us/blog/happy-birthday-secure-by-design.yml","en-us/blog/happy-birthday-secure-by-design",{"_path":2302,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2303,"content":2309,"config":2314,"_id":2316,"_type":14,"title":2317,"_source":16,"_file":2318,"_stem":2319,"_extension":19},"/en-us/blog/hosted-runners-for-gitlab-dedicated-now-in-limited-availability",{"title":2304,"description":2305,"ogTitle":2304,"ogDescription":2305,"noIndex":6,"ogImage":2306,"ogUrl":2307,"ogSiteName":686,"ogType":687,"canonicalUrls":2307,"schema":2308},"Hosted runners for GitLab Dedicated: Now in limited availability"," Simplify CI/CD infrastructure management with hosted runners for GitLab Dedicated, a fully managed solution that handles all aspects of runner infrastructure.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664751/Blog/Hero%20Images/AdobeStock_640077932.jpg","https://about.gitlab.com/blog/hosted-runners-for-gitlab-dedicated-now-in-limited-availability","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Hosted runners for GitLab Dedicated: Now in limited availability\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Gabriel Engel\"}],\n        \"datePublished\": \"2025-01-23\",\n      }",{"title":2304,"description":2305,"authors":2310,"heroImage":2306,"date":2311,"body":2312,"category":848,"tags":2313},[1496],"2025-01-23","We are excited to announce that hosted runners for [GitLab Dedicated](https://about.gitlab.com/dedicated/), our single-tenant SaaS solution, have transitioned from [beta](https://about.gitlab.com/blog/hosted-runners-for-gitlab-dedicated-available-in-beta/) to limited availability, marking a significant milestone in our commitment to simplifying CI/CD infrastructure management for our customers.\n\n## Streamlined CI/CD infrastructure management\n\nManaging runner infrastructure has traditionally been a complex undertaking, requiring dedicated resources and expertise to maintain optimal performance. Hosted runners for GitLab Dedicated eliminates these challenges by providing a fully managed solution that handles all aspects of runner infrastructure. This allows your teams to focus on what matters most – building and deploying great software.\n\n## Key benefits\n\n### Reduced operational overhead\n\nBy choosing hosted runners, you can eliminate the complexity of provisioning, maintaining, and securing your runner infrastructure. Our fully managed service handles all aspects of runner operations, from deployment to updates and security patches.\n\n### Automatic scaling\n\nHosted runners automatically scale to match your CI/CD demands, ensuring consistent performance during high-traffic periods and for large-scale projects. This dynamic scaling capability means you'll always have runners available to pick up your CI/CD jobs and ensure optimal efficiency of your development teams.\n\n### Cost optimization\n\nWith hosted runners, you only pay for the resources you actually use. This consumption-based model eliminates the need to maintain excess capacity for peak loads, potentially reducing your infrastructure costs while ensuring resources are available when needed.\n\n### Enterprise-grade security\n\nFollowing the same security principles as GitLab Dedicated, hosted runners provide complete isolation from other tenants and are secure by default. Jobs are executed in fully-isolated VMs with no inbound traffic allowed. This means you can maintain the highest security standards without the complexity of implementing and maintaining security measures yourself.\n\n## Introducing native Arm64 support\n\nOur hosted runners now include native Arm64 support in addition to our existing x86-64 runners, offering significant advantages for modern development workflows.\n\n### Enhanced performance for Arm-based development\n\nNative Arm64 runners enable you to build, test, and deploy Arm-based applications in their native environment, ensuring optimal performance and compatibility. Teams developing Docker images or services targeting Arm-based cloud platforms can see build times cut significantly, accelerating their development cycles and deployments.\n\n### Cost-efficient computing\n\nArm-based runners can significantly reduce your computing costs, due to their efficient processing architecture and lower cost per minute. For compatible jobs, this means more affordable pipeline execution.\n\n### Native building capabilities\n\nWith support for both x86-64 and Arm64 architectures, you can:\n- build and test applications natively on either architecture\n- create multi-architecture container images efficiently\n- validate cross-platform compatibility in your CI/CD pipeline\n- optimize your delivery pipeline for specific target platforms\n- eliminate the performance overhead of emulation when building for Arm targets\n\nThis dual-architecture support ensures you have the flexibility to choose the right environment for each specific workload while maintaining a consistent and efficient CI/CD experience across all your projects.\n\n## Available runner sizes\n\nWe're expanding our runner offerings to include both x86-64 and Arm64 architectures with a range of configurations. The following sizes are available:\n\n| Size | vCPUs | Memory | Storage |\n|------|--------|---------|----------|\n| Small    | 2      | 8 GB    | 30 GB    |\n| Medium    | 4      | 16 GB   | 50 GB    |\n| Large    | 8      | 32 GB   | 100 GB   |\n| X-Large   | 16     | 64 GB   | 200 GB   |\n| 2X-Large  | 32     | 128 GB  | 200 GB   |\n\nThis expanded size support allows you to optimize your CI/CD pipeline performance based on your application's specific requirements.\n\n## What's next for hosted runners\n\nWe plan to release hosted runners in general availability in May 2025. The release includes compute minute visualization to help you better understand and control your CI/CD usage across your organization.\n\nWe'll be expanding our hosted runners offering with several new features coming later this year:\n- Network controls for enhanced security and compliance\n- MacOS runners to support application development for the Apple ecosystem\n- Windows runners for .NET and Windows-specific workloads\n\nThese additions will provide even more flexibility and coverage for your CI/CD needs, allowing you to consolidate all your build and test workflows on GitLab Dedicated hosted runners.\n\nReady to simplify your CI/CD infrastructure? Contact your GitLab representative or [reach out to our sales team](https://about.gitlab.com/dedicated/) to learn more about hosted runners for GitLab Dedicated.\n",[9,496,719,994,109,186],{"slug":2315,"featured":6,"template":698},"hosted-runners-for-gitlab-dedicated-now-in-limited-availability","content:en-us:blog:hosted-runners-for-gitlab-dedicated-now-in-limited-availability.yml","Hosted Runners For Gitlab Dedicated Now In Limited Availability","en-us/blog/hosted-runners-for-gitlab-dedicated-now-in-limited-availability.yml","en-us/blog/hosted-runners-for-gitlab-dedicated-now-in-limited-availability",{"_path":2321,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2322,"content":2328,"config":2333,"_id":2335,"_type":14,"title":2336,"_source":16,"_file":2337,"_stem":2338,"_extension":19},"/en-us/blog/how-carrefour-and-thales-are-evolving-their-ci-cd-platforms",{"title":2323,"description":2324,"ogTitle":2323,"ogDescription":2324,"noIndex":6,"ogImage":2325,"ogUrl":2326,"ogSiteName":686,"ogType":687,"canonicalUrls":2326,"schema":2327},"How Carrefour and Thales are evolving their CI/CD platforms","Learn how a large retailer and an aerospace and defense company are using GitLab to evolve their CI/CD platforms to increase developer productivity.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662061/Blog/Hero%20Images/cicdcover.png","https://about.gitlab.com/blog/how-carrefour-and-thales-are-evolving-their-ci-cd-platforms","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How Carrefour and Thales are evolving their CI/CD platforms\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kristina Weis\"}],\n        \"datePublished\": \"2024-02-05\",\n      }",{"title":2323,"description":2324,"authors":2329,"heroImage":2325,"date":2330,"body":2331,"category":972,"tags":2332},[947],"2024-02-05","An efficient and secure CI/CD platform can be especially critical for some organizations — say, a large multinational retailer or an aerospace and defense company. Fortunately, Samuel Le Garec, a technical architect from Carrefour, and Jordan Dubié, Chief Product Owner for the software engineering environment at Thales, joined GitLab for a roundtable discussion at our [DevSecOps World Tour](https://about.gitlab.com/events/devsecops-world-tour/) stop in Paris. They shared their experiences and lessons learned from building CI/CD platforms for thousands of developers, and improving productivity and security along the way.\n\nHere are some of the highlights from their conversation.\n\n**Can you tell me about yourselves and your team?**\n\nDubié: I am the Chief Product Owner of the software factory, which is the software development environment of the Thales Group. [Thales](https://www.thalesgroup.com/en) is a French industrial group that operates in the aerospace, defense, security, and digital identity sectors. Thales is 80,000 people, including 30,000 engineers, specifically 15,000 software engineers. \n\nToday, our team is a little less than 50 people. We also do the build and the run and have a part, therefore, in 24-7 support, following the sun. We have different instances, and we have domains of different sensitivity. So we have several platforms, all self-hosted. On each of these platforms, we deploy the entire environment of the software factory. We also run a part of it, and then we are supported by other teams who take over these activities.\n\nLe Garec: I am an architect at [Carrefour](https://www.carrefour.com/en). I’m responsible for the engineering platform within the software factory and implementing the CI/CD platforms for the development teams. We have between 1,000 and 1,500 developers, so they commit like crazy. Today, I have a team of about 15 people. Our primary focus is to evolve the CI/CD platform, operate it, and manage incidents. We do that 24-7 today. We work mainly for the IT department in France. Then, I have other people who set up all the CI/CD templating and blueprints, the goal being to speed up the project as much as possible.\n\n**Can you share some numbers to give us a sense for the scale of GitLab in your organization?**\n\nDubié: Since we’ve been using GitLab, we’re at 30,000 projects, 70,000 issues, and 280,000 merge requests.\n\nLe Garec: At Carrefour, I think we have less GitLab experience than Jordan since we got our GitLab subscription at the beginning of the year. We have over 10,000 projects today on our CI/CD platform and then many pipeline executions, builds, and deployments that are as automated as possible. And we have 100,000 commits per month, to give you an idea of our activity.\n\n**What was it like before GitLab?**\n\nDubié: It was a very heterogeneous environment. We had all these different business entities, each with their own IT teams that were on site. I was in Toulouse, but there was an entity in Bordeaux, as well. The different environments in Bordeaux, Toulouse, Valence, and Paris were completely separate platforms. That was a major obstacle to collaboration in the group. We had all these heterogeneous platforms with tools that, most of the time, hadn’t been updated in three to four years. So, in terms of functionality, we were far behind the market's state of the art.\n\nLe Garec: We were deploying many different tools. We realized that maintaining our platform was becoming more and more complicated as the maturity of the development teams increased. They always asked us for more tools, and we reached a point where we couldn’t afford to do it anymore. That’s when we thought about an all-in-one solution. And that’s when we chose GitLab.\n\n**Is GitLab new for you? What are your initial goals?**\n\nLe Garec: GitLab is new for us — we started using it in April of this year. We are using GitLab Ultimate SaaS. Our goal is to use as many GitLab Ultimate features as possible. Our plan for the first two or three years is to migrate our source code to GitLab. So far, we’ve managed to move off of Bitbucket. Our next goal is to get rid of Jenkins and move to GitLab CI.\n\n> Learn [how to migrate from Jenkins to GitLab](https://about.gitlab.com/blog/jenkins-to-gitlab-migration-made-easy/).\n\n**How has GitLab helped to improve the speed and quality of your delivery processes?**\n\nDubié: We bet everything on automation. We go all out on everything that can support CI/CD so that developers can get feedback as quickly as possible. We also use SAST, DAST, secret detection, and software composition analysis.\n\nOne thing that was important for us was autonomy. We try to give our developers as much autonomy as possible so that people can create their own group projects. It seems very simple, but in the previous platform with Bitbucket, you had to go through tickets to have that; it was not in the hands of the developers. Today, there is much more autonomy, which allows them to go faster.\n\nWe also benefit from common, shared features; the shared runners, for example, are something we appreciate. We are already working on them because they will add a lot of value for developers who today have difficulties having a development environment that meets their expectations.\n\n**How would you describe an ideal software delivery process with GitLab?**\n\nLe Garec: For me, an almost ideal delivery process is full automation with everything automated — the build, the test, the releases, the versioning, and the deployment, using deployment techniques such as canary deployments and feature flags. For me, that’s something we want and need to go to, at Carrefour at least.\n\n**What are the reactions of the users or developers using GitLab?**\n\nLe Garec: They are pleased. One of the reasons we went to GitLab was the lack of features we had on Bitbucket. Bitbucket had some features, but every time you have to add plugins, it’s paid every time. It’s annoying. So that’s why we went to GitLab and the whole set of features that GitLab offers. It pleases the users to have a homogeneous platform where they don’t have to change tools every five minutes. It improves their productivity, and we have fewer incidents.\n\n*Editor's note: This blog post is based on an edited version of the session transcript that was translated from French.*\n",[109,974,9],{"slug":2334,"featured":91,"template":698},"how-carrefour-and-thales-are-evolving-their-ci-cd-platforms","content:en-us:blog:how-carrefour-and-thales-are-evolving-their-ci-cd-platforms.yml","How Carrefour And Thales Are Evolving Their Ci Cd Platforms","en-us/blog/how-carrefour-and-thales-are-evolving-their-ci-cd-platforms.yml","en-us/blog/how-carrefour-and-thales-are-evolving-their-ci-cd-platforms",{"_path":2340,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2341,"content":2346,"config":2351,"_id":2353,"_type":14,"title":2354,"_source":16,"_file":2355,"_stem":2356,"_extension":19},"/en-us/blog/how-cube-uses-gitlab-to-increase-efficiency-and-productivity",{"title":2342,"description":2343,"ogTitle":2342,"ogDescription":2343,"noIndex":6,"ogImage":2133,"ogUrl":2344,"ogSiteName":686,"ogType":687,"canonicalUrls":2344,"schema":2345},"Cube reduces toolchain complexity and speeds software delivery with GitLab","Software maker shares how the DevSecOps Platform helps improve customer collaboration and streamline releases.","https://about.gitlab.com/blog/how-cube-uses-gitlab-to-increase-efficiency-and-productivity","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Cube reduces toolchain complexity and speeds software delivery with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"GitLab\"}],\n        \"datePublished\": \"2023-02-07\",\n      }",{"title":2342,"description":2343,"authors":2347,"heroImage":2133,"date":2348,"body":2349,"category":972,"tags":2350},[1751],"2023-02-07","Six years ago, [Cube](https://cube.nl/), a software development company based in the Netherlands, struggled with a fragmented and siloed toolchain. The company also wanted a comprehensive solution that would pull together development, security, and operations teams and create a single source of truth for better collaboration with their customers. So they opted for GitLab’s DevSecOps Platform.\n\nOperations Manager Mans Booijink and Lead Developer Remi Buijvoets sat down with GitLab to share how moving to an all-in-one DevSecOps platform has made a significant and positive difference at Cube – internally and with customers – and why they are happy with the move.\n\nBefore diving into their migration story, here's a snapshot of the improvements Cube has achieved with GitLab:\n\n- Improved [CI/CD](/topics/ci-cd/) delivery speed\t\n- Improved service-level agreement (SLA) response time\n- 80% of Cube clients are actively working in GitLab\n- Single source of truth collaboration\n\n![image of Mans Booijink](https://about.gitlab.com/images/blogimages/MansBooijinkCube.jpg) | ![image of Remi Buijvoets](https://about.gitlab.com/images/blogimages/RemiBuijvoetsCube.jpg)\nMans Booijink | Remi Buijvoets\n\n**Why did Cube make the switch to GitLab?**\n\nBefore making the switch, we used a combination of Bitbucket, Trello, and Jira. The combination caused a [fragmented, siloed toolchain](/blog/battling-toolchain-technical-debt/). There were a lot of opportunities for improving efficiency. So we started using GitLab because we wanted a DevOps system that includes ticket management, security, and customer collaboration. Not only does GitLab operate efficiently, but adoption is also fast and easy. In fact, we tripled our GitLab user base from 20 to nearly 70 in the past three years. Now almost the entire Cube organization uses GitLab. Our clients and colleagues (designers, developers, and project managers) can communicate easily by working in the same GitLab environment. \n\n**Did Cube try anything else before GitLab?**\n\nWe tried out other tools before moving to GitLab. But GitLab offered everything we needed – ticket management, CI/CD, DevOps, versioning, file management, and security. It didn’t take long to realize that GitLab was perfect because we wanted to have one tool where we all work together with our clients and team.\n\n**Now that Cube uses GitLab, how has your toolchain changed?**\n\nGitLab has simplified everything into a single source of truth. We deploy to a private cloud in the Netherlands, and we integrated Sentry into GitLab for error monitoring. Still, otherwise, everything we do is in GitLab.\n\n**How has GitLab CI/CD helped Cube?**\n\nGitLab CI helps us automate the software development process by using GitLab pipelines and a runner to deploy our code. Within the pipelines, we run linters to check code quality. Also, Unit and functional tests are executed to ensure the functioning of the application. When an error occurs or when a test fails, the pipeline will fail. GitLab CI adds value to our software development lifecycle because it prevents bugs from being deployed and helps deploy features while other features are still in development. In addition, it helps us monitor our projects’ quality, which is essential.\n\nGitLab CI surely helps in the speed of delivery, but also a lot in facilitating rollbacks when a release accidentally contains an error. We use a release schedule, and GitLab helps us to automate most of the work so that we can deliver right on time.\n\nGitLab CD improves the speed of our code deployments. When the pipelines succeed, developers can ensure everything works as it should. As a result, developers can focus more on the development itself and don’t have to lose focus by giving thoughts on the deployment. We have also introduced a local machine that builds releases. The machine is hosted on-premises and has a lot of resources. Multiple GitLab Runners use this machine to build releases. Using the GitLab Runners with an on-premises computer was easy to configure.\n\n**How have GitLab’s Agile capabilities helped your company become more efficient?**\n\nBefore GitLab, we used a variety of communication channels with our customers. Now GitLab gives us a central, accessible place for all communications. We also use [GitLab for Agile development](/solutions/agile-delivery/). We have our epics to manage bigger development projects, and we also utilize milestones. We do four to six releases weekly, and we all manage them by creating milestones that everyone can see, including the client and the development team. We provide all tickets with requirements, estimated time, when we intend to release it, who has to test it, etc. We use GitLab for 90% of our project management, Agile management, and working functionalities, which is proving very effective.\n\n**How do you measure the success of your GitLab migration?**\n\nWe measure the lead time of delivery. The results of each separate phase in the delivery are accurately logged. This way we can demonstrate that we comply with the agreements made to our customers. We also keep track of how efficient the different phases during the development process are, and whether they improve compared to the past.\n\nBecause we use GitLab integrally throughout the process, it is a very valuable and useful source of information.",[9,974,109],{"slug":2352,"featured":6,"template":698},"how-cube-uses-gitlab-to-increase-efficiency-and-productivity","content:en-us:blog:how-cube-uses-gitlab-to-increase-efficiency-and-productivity.yml","How Cube Uses Gitlab To Increase Efficiency And Productivity","en-us/blog/how-cube-uses-gitlab-to-increase-efficiency-and-productivity.yml","en-us/blog/how-cube-uses-gitlab-to-increase-efficiency-and-productivity",{"_path":2358,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2359,"content":2365,"config":2370,"_id":2372,"_type":14,"title":2373,"_source":16,"_file":2374,"_stem":2375,"_extension":19},"/en-us/blog/how-devsecops-drives-business-success",{"title":2360,"description":2361,"ogTitle":2360,"ogDescription":2361,"noIndex":6,"ogImage":2362,"ogUrl":2363,"ogSiteName":686,"ogType":687,"canonicalUrls":2363,"schema":2364},"How DevSecOps drives business success","Learn the benefits of DevSecOps, including how it drives ROI.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663975/Blog/Hero%20Images/devsecopssurvey.png","https://about.gitlab.com/blog/how-devsecops-drives-business-success","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How DevSecOps drives business success\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sharon Gaudin\"}],\n        \"datePublished\": \"2023-07-24\",\n      }",{"title":2360,"description":2361,"authors":2366,"heroImage":2362,"date":2367,"body":2368,"category":10,"tags":2369},[756],"2023-07-24","\nDevSecOps is an evolution of DevOps — but it’s more than just adding the word “Security” in between \"Development\" and \"Operations.\" It's about bringing everyone into the security team and [building security](/the-source/security/how-to-strengthen-security-by-applying-devsecops-principles/) into the entire software development lifecycle. Although DevSecOps is likely talked about more in coding circles than in boardrooms, the benefits of DevSecOps extend to the entire organization, helping teams deliver software faster without sacrificing quality or security.\n\nBut what exactly are the business benefits of DevSecOps? In this blog post, we'll dive into the top ways DevSecOps can help organizations drive business results and ROI.\n\n> Want to dig deeper into the basics of DevSecOps and how to use it to drive business success? [Download our guide to learn more](https://page.gitlab.com/resources-ebook-devsecops-success.html?utm_campaign=devsecopsplat&utm_content=ebookdevsecopssuccess).\n\n## How DevSecOps can benefit businesses\nHere are a few of the ways adopting DevSecOps can benefit a business:\n* Moving to a single platform [reduces money spent on toolchain](/the-source/platform/devops-teams-want-to-shake-off-diy-toolchains-a-platform-is-the-answer/) licenses and management\n* Focusing on security helps secure the business and its customers\n* Increasing productivity leads to faster time to market, which means staying ahead of competitors\n* Increasing security enables DevOps teams to identify issues that could ultimately hurt the brand and break customer and partner trust\n* Catching and fixing security vulnerabilities reduces legal liability connected to breaches\n* Having DevOps teams work cross-functionally in a single tool fosters collaboration in the software development team and across the entire company\n* Managing access controls, policies, and audits in one platform eases and promotes compliance\n* Unifying with a platform makes it easier to be cloud agnostic, which makes a company more resistant to vendor outages\n* Increasing visibility into every component in the [software supply chain](https://about.gitlab.com/blog/the-ultimate-guide-to-software-supply-chain-security/) boosts security and reliability\n* Automating scanning takes human error out of the equation by reducing the chances of having vulnerabilities that hackers can exploit\n\n## How DevSecOps drives ROI\n“Central for any executive is ROI and if a decision will bring their business forward or backward,” says [Ayoub Fandi](https://gitlab.com/ayofan), senior field security engineer at GitLab. “A DevSecOps platform brings all of the features, security tools, and automation of DevSecOps together in a single app so there’s no buying, stitching, and maintaining a complicated jumble of tools. It also means a company isn’t paying for all of those licensing costs, subscription fees, and maintenance expenses. Each year, companies spend more and more on technology, so if they can find a way to reduce their spending on that, it’ll be very welcome to executives.”\n\nBy helping protect a company’s brand, enabling the organization to stay ahead in a competitive field and remain compliant, and giving executives visibility over what’s causing slowdowns or increasing velocity, DevSecOps can be a valuable business tool.\n\n## What is a DevSecOps platform?\nA [comprehensive DevSecOps platform](https://about.gitlab.com/platform/) brings all of the features, security controls, and automation of DevSecOps together in one end-to-end application, so there’s no buying and supporting a complicated jumble of tools.\n\n“If I were in a company’s buying seat, I would be looking at DevSecOps,” says Fandi. “Executives want to worry less about compliance issues and security breaches that could have a big impact on their revenue, their ability to grow the company, and customers’ confidence in doing business with them. With DevSecOps, they can worry less about all of that.”\n\n_Explore how DevSecOps and a DevSecOps platform can help organizations save money, boost competitiveness, increase security, and more. [Download our comprehensive guide to get started](https://page.gitlab.com/resources-ebook-devsecops-success.html?utm_campaign=devsecopsplat&utm_content=ebookdevsecopssuccess)._\n",[496,761,9],{"slug":2371,"featured":6,"template":698},"how-devsecops-drives-business-success","content:en-us:blog:how-devsecops-drives-business-success.yml","How Devsecops Drives Business Success","en-us/blog/how-devsecops-drives-business-success.yml","en-us/blog/how-devsecops-drives-business-success",{"_path":2377,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2378,"content":2384,"config":2389,"_id":2391,"_type":14,"title":2392,"_source":16,"_file":2393,"_stem":2394,"_extension":19},"/en-us/blog/how-gitlab-duo-helps-secure-and-thoroughly-test-ai-generated-code",{"title":2379,"description":2380,"ogTitle":2379,"ogDescription":2380,"noIndex":6,"ogImage":2381,"ogUrl":2382,"ogSiteName":686,"ogType":687,"canonicalUrls":2382,"schema":2383},"Developing GitLab Duo: Secure and thoroughly test AI-generated code","Learn step-by-step how to enhance AI-generated code reliability and security using GitLab Duo and GitLab Pages (includes code samples and prompts).","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097183/Blog/Hero%20Images/Blog/Hero%20Images/blog-hero-banner-1-0178-820x470-fy25_7JlF3WlEkswGQbcTe8DOTB_1750097183481.png","https://about.gitlab.com/blog/how-gitlab-duo-helps-secure-and-thoroughly-test-ai-generated-code","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Developing GitLab Duo: Secure and thoroughly test AI-generated code\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David O'Regan\"}],\n        \"datePublished\": \"2024-05-30\",\n      }",{"title":2379,"description":2380,"authors":2385,"heroImage":2381,"date":2386,"body":2387,"category":781,"tags":2388},[1886],"2024-05-30","___Generative AI marks a monumental shift in the software development industry, making it easier to develop, secure, and operate software. Our new blog series, written by our product and engineering teams, gives you an inside look at how we create, test, and deploy the AI features you need integrated throughout the enterprise. Get to know new capabilities within GitLab Duo and how they will help DevSecOps teams deliver better results for customers.___\n\nAs AI becomes increasingly integral to software development, ensuring the security and thorough testing of AI-generated code is paramount. This article is a step-by-step guide to combining [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our suite of AI features to powering the DevSecOps workflow, and [GitLab Pages](https://docs.gitlab.com/ee/user/project/pages/) to secure and thoroughly test AI-generated code. You'll discover how to mitigate common risks, including how to automatically generate tests, test code, and deploy test reports – all to enhance the reliability of your AI-generated code.\n\n> Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Watch today!](https://about.gitlab.com/seventeen/)\n\n## Challenges in AI-generated code\n\nAI-generated code often faces issues such as:\n\n- Mismatched algorithms: Incorrect or suboptimal algorithms can be generated.\n- Dependency problems: AI may include dependencies that are outdated or incompatible.\n- Security vulnerabilities: AI might generate code with potential security flaws.\n\nAI-generated code often faces issues such as mismatched algorithms, dependency problems, and security vulnerabilities. A [recent study published by the Association of Computing Machinery](https://dl.acm.org/doi/pdf/10.1145/3613904.3642596) on ChatGPT’s responses to programming questions found that 52% of the answers contained incorrect information, and 77% were overly verbose. Despite these shortcomings, users preferred ChatGPT’s comprehensive and well-articulated answers 35% of the time, even overlooking misinformation 39% of the time. Addressing these challenges requires the use of advanced tools and frameworks.\n\n## GitLab’s approach to AI security and testing\n\nGitLab has a comprehensive content strategy focused on integrating security measures within the development workflow. By leveraging GitLab Duo for AI-powered code generation and GitLab Pages for embedding test reports, developers can ensure their AI-generated code is both secure and reliable.\n\nHere is a step-by-step guide to pair GitLab Duo and GitLab Pages to ensure secure and thoroughly tested AI-generated code by implementing a [Flask web server](https://flask.palletsprojects.com/en/3.0.x/).\n\n### 1. Create a new project on GitLab.com\n\n- Go to [GitLab.com](http://GitLab.com).\n- Click on the \"New project\" button.\n- Choose \"Create blank project\".\n- Enter a project name (e.g., AI_Code_Security).\n- Set the visibility level (Public, Internal, or Private).\n- Click \"Create project\".\n\n### 2. Enable GitLab Duo Code Suggestions\n\n- Navigate to your project.\n- Click on the \"Web IDE\" button to open the Web IDE.\n- Ensure that GitLab Duo features like Code Suggestions and Duo Chat are enabled. \n- Start coding in the [Web IDE](https://docs.gitlab.com/ee/user/project/web_ide/). As you type, GitLab Duo will provide code suggestions to help you write code more efficiently.\n\n### 3. Create a Flask web server\n\nYou can create a Flask web server using the comment (highlighted in green) in the screenshot below.\n\n![DGD testing - image 1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097192/Blog/Content%20Images/Blog/Content%20Images/image4_aHR0cHM6_1750097192520.png)\n\n### 4. Generate tests with GitLab Duo\n\nUnit tests are essential for validating the functionality of the generated code. Use GitLab Duo’s `/tests` command to [generate testing suggestions directly in the Web IDE](https://docs.gitlab.com/ee/user/gitlab_duo_chat_examples.html#write-tests-in-the-ide). This command can be tailored with additional instructions to focus on specific aspects such as performance, regression, or using particular frameworks.\n\n#### Example usage in Web IDE:\n\n- Select the code for which you want to generate tests.\n- Use the command `/tests` followed by additional instructions if needed.\n\n![DGD testing - image 2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097192/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750097192521.png)\n\n### 5. Identify issues with AI-generated code using GitLab Duo Chat\n\nUse GitLab Duo Chat to review and refine AI-generated code. For instance, let's check our Flask web server code for security vulnerabilities:\n\n```unset\nPrompt: Review this code for potential security vulnerabilities and dependency issues.\n\n```\n\n![DGD testing - image 3](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097192/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750097192523.png)\n\nGitLab Duo Chat can help identify the vulnerabilities in the above code.\n\n### 6. Generate test reports\nAfter running your tests, generate a test report that will be deployed using GitLab Pages.\n\n```unset\n\nPrompt: Write me a python script to generate a test report that will be deployed using \nGitLab Pages.\n\n```\n\n![DGD testing - image 4](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097192/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750097192525.png)\n\nWhat's happening here?\n\n- The script ensures the test_reports directory exists.\n- It runs the `test_server.py` file using `subprocess.run()`, capturing the output.\n- The raw output is saved to `test_reports/test_output.txt`.\n- An HTML report is generated, embedding the test output within `\u003Cpre>` tags for readability, and saved as `test_reports/index.html`.\n\n### 7. Deploy the test report with GitLab Pages\n\nUse [GitLab Pages](https://docs.gitlab.com/ee/user/project/pages/) to host and display the test report. Here’s the configuration for our `.gitlab-ci.yml` file to deploy the test report.\n\n```python\n\nstages:\n  - test\n  - deploy\ntest_job:\n  stage: test\n  script:\n    - python generate_test_report.py\n  artifacts:\n    paths:\n      - test_reports/\npages:\n  stage: deploy\n  script:\n    - mv test_reports public\n  artifacts:\n    paths:\n      - public\n\n ```\n\nWith this setup, the `test_job` stage runs the Python script to generate the test report. The `pages` stage moves the `test_reports` directory to `public`, which GitLab Pages uses to serve the content.\n\n### 8. Embedding test reports in MR widgets\n\nEmbedding the [test reports in MR widgets](https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html) provides immediate visibility into the testing outcomes, ensuring transparency and reliability. This can be done by including the test report as an artifact in your CI/CD pipeline configuration:\n\n```python\n\nstages:\n  - build\n  - test\n  - deploy\n\nbuild_job:\n  stage: build\n  script:\n    - echo \"Building the project...\"\n    - # Your build commands here\n\ntest_job:\n  stage: test\n  script:\n    - mkdir -p test-reports\n    - python test_server.py > test-reports/results.xml\n  artifacts:\n    when: always\n    reports:\n      junit: test-reports/results.xml\n    paths:\n      - test-reports/results.xml\n\npages:\n  stage: deploy\n  script:\n    - mkdir .public\n    - mv test-reports .public/\n  artifacts:\n    paths:\n      - .public\n\n```\nBy including the test report as an artifact and specifying it in the reports section, GitLab will automatically display the test results in the MR widgets, providing immediate visibility into the testing outcomes and enhancing transparency and reliability.\n\n### Case study: AI reliability with security policies and scanners\n\nImagine a scenario where an AI-generated code snippet introduces a dependency that has known vulnerabilities. By using GitLab Duo and its security policies, this dependency would be flagged during the code generation process. Let’s consider an example where a snippet was generated by AI:\n\n```python\n\nimport os\nfrom flask import Flask, request\n\napp = Flask(__name__)\n\n@app.route('/search')\ndef search():\n    query = request.args.get('query')\n    execute_os_command(query)\n    return 'You searched for: ' + query\n\ndef execute_os_command(command):\n    os.system(command)\n\nif __name__ == '__main__':\n    app.run()\n\n```\n\nIn this example, the search endpoint is vulnerable to OS command injection. By leveraging GitLab's Static Application Security Testing ([SAST](https://docs.gitlab.com/ee/user/application_security/sast/)) component, this vulnerability would be detected during the CI/CD pipeline.\n\n#### Integrate SAST scanning to detect vulnerabilities\n\nGitLab SAST automatically analyzes your code for security vulnerabilities. Here’s how it can be integrated into your `.gitlab-ci.yml` file to scan for issues:\n\n```python\n\nstages:\n  - build\n  - test\n  - sast\n  - deploy\n\nbuild_job:\n  stage: build\n  script:\n    - echo \"Building the project...\"\n    - # Your build commands here\n\ntest_job:\n  stage: test\n  script:\n    - python test_server.py > test-reports/results.xml\n  artifacts:\n    when: always\n    reports:\n      junit: test-reports/results.xml\n    paths:\n      - test-reports/results.xml\n\nsast_job:\n  stage: sast\n  script:\n    - echo \"Running SAST...\"\n  artifacts:\n    reports:\n      sast: gl-sast-report.json\n  only:\n    - branches\n\npages:\n  stage: deploy\n  script:\n    - mv test-reports public\n  artifacts:\n    paths:\n      - public\n\n```\n\nIn this configuration, the `sast_job` stage runs SAST to detect vulnerabilities in the code, producing a report (`gl-sast-report.json`) that will be included in the pipeline artifacts! By integrating security policies and robust testing frameworks, GitLab Duo helps customers ensure that their AI-generated code is both efficient and secure.\n\n## Get started today\nThe integration of AI in software development brings significant benefits but also introduces new challenges. By using tools like GitLab Duo and GitLab Pages, developers can ensure that their AI-generated code is secure, well-tested, and reliable. Explore these tools today and join the conversation on enhancing AI security and testing!\n\n> [Start a trial of GitLab Ultimate](https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/blog&glm_content=default-saas-trial) today to access GitLab Duo and GitLab Pages.\n\n## Read more of the \"Developing GitLab Duo\" series\n\n- [Developing GitLab Duo: How we validate and test AI models at scale](https://about.gitlab.com/blog/developing-gitlab-duo-how-we-validate-and-test-ai-models-at-scale/)\n- [Developing GitLab Duo: AI Impact analytics dashboard measures the ROI of AI](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/)\n- [Developing GitLab Duo: How we are dogfooding our AI features](https://about.gitlab.com/blog/developing-gitlab-duo-how-we-are-dogfooding-our-ai-features/)\n- [Developing GitLab Duo: Blending AI and Root Cause Analysis to fix CI/CD pipelines](https://about.gitlab.com/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd/)\n",[717,9,827,694],{"slug":2390,"featured":6,"template":698},"how-gitlab-duo-helps-secure-and-thoroughly-test-ai-generated-code","content:en-us:blog:how-gitlab-duo-helps-secure-and-thoroughly-test-ai-generated-code.yml","How Gitlab Duo Helps Secure And Thoroughly Test Ai Generated Code","en-us/blog/how-gitlab-duo-helps-secure-and-thoroughly-test-ai-generated-code.yml","en-us/blog/how-gitlab-duo-helps-secure-and-thoroughly-test-ai-generated-code",{"_path":2396,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2397,"content":2402,"config":2408,"_id":2410,"_type":14,"title":2411,"_source":16,"_file":2412,"_stem":2413,"_extension":19},"/en-us/blog/how-gitlab-measures-red-team-impact-the-adoption-rate-metric",{"title":2398,"description":2399,"ogTitle":2398,"ogDescription":2399,"noIndex":6,"ogImage":922,"ogUrl":2400,"ogSiteName":686,"ogType":687,"canonicalUrls":2400,"schema":2401},"How GitLab measures Red Team impact: The adoption rate metric","Follow our journey to develop and implement better metrics, including how we used GitLab to track our results end-to-end. Also find out the lessons learned along the way.","https://about.gitlab.com/blog/how-gitlab-measures-red-team-impact-the-adoption-rate-metric","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How GitLab measures Red Team impact: The adoption rate metric\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Chris Moberly\"}],\n        \"datePublished\": \"2025-03-05\",\n      }",{"title":2398,"description":2399,"authors":2403,"heroImage":922,"date":2405,"body":2406,"category":694,"tags":2407},[2404],"Chris Moberly","2025-03-05","In early 2024, we started a journey to implement better metrics for [our\ninternal Red\nTeam](https://handbook.gitlab.com/handbook/security/security-operations/red-team/).\nOur first iteration focused on what we now call the adoption rate metric,\nwhich measures how often the recommendations our team makes are accepted and\nimplemented.\n\n\nChoosing this metric was very deliberate. While there are many ways to\nmeasure a Red Team's impact, we wanted to start with something fundamental:\nAre we actually driving meaningful security improvements? The adoption rate\ndirectly ties our work to real security outcomes, and we could measure it\nusing tools and processes we already had in place.\n\n\nIn this article, you'll discover how we used GitLab to track these results\nend-to-end, some lessons we learned (including what we would have done\ndifferently), and our plans to tackle the next set of metrics.\n\n\n## How we implemented the adoption rate metric\n\n\nWe use GitLab extensively for our Red Team planning, execution, and\nreporting. Every operation wraps up with a report that's written in markdown\nin a dedicated GitLab project. Each report contains a section called\n\"Recommendations\" with a list of suggestions to make GitLab more secure.\n\n\nThose recommendations are always linked to a dedicated issue, which we open\nin the project closest to the team who can address it. If we're suggesting a\nproduct feature, it goes directly in that tracker. If it's a detection\ncapability, it goes into the detections as code repository. We always assign\na directly responsible individual (DRI) in the group that owns that space,\nand we use [this issue\ntemplate](https://gitlab.com/gitlab-com/gl-security/security-operations/redteam/redteam-public/resources/red-team-issue-templates/-/blob/main/.gitlab/issue_templates/recommendation.md?ref_type=heads)\nto ensure consistency in describing the problem, the risk, and potential\nsolutions.\n\n\n![Red team -\nrecommendation-example](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674984/Blog/Content%20Images/recommendation-example__1_.png)\n\n\nHere's where the tracking logistics come in. We use GitLab labels to\nclassify the recommendation across three categories:\n\n\n- Detections and alerts (`RTRec::Detection`)  \n\n- Security controls (`RTRec::Control`)  \n\n- Processes and procedures (`RTRec::Process`)\n\n\nWe then use another set of labels to follow the lifecycle of that\nrecommendation – from review all the way through adoption:\n\n\n- Under review (`RecOutcome::UnderReview`)  \n\n- Accepted and actively being worked on (`RecOutcome::InProgress`)  \n\n- Accepted but backlogged (`RecOutcome::Backlogged`)  \n\n- Accepted but blocked (`RecOutcome::Blocked`)  \n\n- Fully adopted and closed (`RecOutcome::Adopted`)  \n\n- Partially adopted and closed (`RecOutcome::PartiallyAdopted`)  \n\n- Not adopted and closed (`RecOutcome::NotAdopted`)\n\n\n## How we stay on top of recommendations\n\n\nWe use a new GitLab feature called [\"GitLab Query Language\"\n(GLQL)](https://docs.gitlab.com/ee/user/glql/) to build a dynamic Security\nRecommendations Dashboard inside a GitLab issue.\n\n\nThis issue allows us to quickly identify things like:\n\n\n- open recommendations that haven't been updated recently  \n\n- open recommendations that have been backlogged for an extended period of\ntime  \n\n- closed recommendations that weren't properly labeled with an adoption\noutcome\n\n\nWe've found this process encourages the Red Team to follow up on stale\nrecommendations, reaching out to the owners and seeing how we can help get\nthem adopted.\n\n\nGLQL is very cool, and allows us to turn a short code block like this:\n\n\n```yaml  \n\n---  \n\ndisplay: table  \n\nfields: title, labels(\"RTRec::*\"), labels(\"RecOutcome::*\"), created,\nupdated  \n\n---  \n\ngroup = \"gitlab-com\"  \n\nAND label = \"RTRec::*\"  \n\nAND opened = true  \n\n```\n\n\n... into a dynamic table like this:\n\n\n![Red Team - GLQL\ntable](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674984/Blog/Content%20Images/glql-table.png)\n\n\nThat table for us is very tactical and we use it to keep things moving.\nBeyond that, we also visualize the adoption rate trends over time. That\nallows us to look at things like quarterly adoption rate percentages, how\nlong different types of recommendations take to adopt and implement, and how\nthese figures vary across departments.\n\n\n## Lessons learned\n\n\n**1. Start with metrics in place; don't wait for your program to mature\nfirst.**\n\n\nEarly in our Red Team's development, we focused more on how we would execute\noperations and less on how we would measure them. The idea of using metrics\nto distill complex operations into simple numbers felt like it might\noversimplify our work. But we've learned that thoughtful metrics don't\nreduce the value of Red Team operations - they help demonstrate our impact\nand guide our program's growth. Starting with clear metrics earlier would\nhave accelerated this growth.\n\n\nImplementing these metrics later meant spending significant time\nreformatting years of historical recommendations to enable consistent\nanalysis. Had we planned for metrics from the start, we could have saved\nourselves a lot of time and effort.\n\n\nWe’re keeping this lesson in mind as we start on our next set of metrics,\nthreat resilience, which we talk about below.\n\n\n**2. Don't operate in a silo.**\n\n\nRed Teams aren't the only groups that provide recommendations in a security\norganization. At GitLab, we have our bug bounty program, our external\npentests, product security, security assurance, and security operations.\n\n\nOn the Red Team, we developed our own recommendations process from scratch.\nIt's been fairly effective, but we have noticed some areas for improvement,\nparticularly around prioritization, project management, and alignment with\nour organization's risk reporting process.\n\n\nWe also noticed that some other teams are really good at these areas such as\nour bug bounty program and the triaging of findings from our external\npentests. Those particular groups are very good at delivering product\nrecommendations, and we've been learning from their approach to improve our\nown delivery methods.\n\n\nSo we've taken our success with visualizing metrics and are integrating\nthese lessons to create a more standard format that can be used across\nteams. This will allow us to leverage things that are working well, like our\nadoption rate metric, and combine them with the more efficiently managed\nprocesses used by other groups to ultimately achieve a higher adoption rate\nand a more secure GitLab.\n\n\n## Next up: Measuring our threat resilience\n\n\nNext up for us is implementing metrics around threat resilience. We want to\nmeasure how well GitLab can prevent, detect, and respond to the threats most\nrelevant to our organization. We're building a dashboard that will help\nvisualize this data, showing our top threat actors and a series of scores\nthat measure how well we defend against their specific techniques.\n\n\nOur goal is to have this dashboard drive decisions around what Red Team\noperations to conduct, what defensive capabilities to improve, and in\ngeneral where we should be investing time and effort across our entire\nsecurity division.\n\n\nWe hope to consolidate our existing tools in this process and are currently\nevaluating solutions. We'll share more info when we've achieved some success\nhere.\n\n\n## Key takeaways and how to get started\n\n\nIf you're looking to measure your Red Team's impact, here's what we've\nlearned:\n\n\n1. Start tracking metrics early, even if they're not perfect.  \n\n2. Focus on actionable metrics first (like adoption rate).  \n\n3. Use your existing tools. We used GitLab and Tableau, but the approach\nworks with any tracking system.  \n\n4. Collaborate across security teams to leverage existing processes when\npossible.\n\n\nWe'd love to hear about your experience with metrics in security so drop a\ncomment below or open an issue in one of our [public\nprojects](https://gitlab.com/gitlab-com/gl-security/security-operations/redteam/redteam-public).\n\n\n## Read more from GitLab's Red Team  \n\n- [Stealth operations: The evolution of GitLab's Red\nTeam](https://about.gitlab.com/blog/stealth-operations-the-evolution-of-gitlabs-red-team/)  \n\n- [How GitLab's Red Team automates C2\ntesting](https://about.gitlab.com/blog/how-gitlabs-red-team-automates-c2-testing/)  \n\n- [How we run Red Team operations\nremotely](https://about.gitlab.com/blog/how-we-run-red-team-operations-remotely/)\n",[694,9,1038],{"slug":2409,"featured":6,"template":698},"how-gitlab-measures-red-team-impact-the-adoption-rate-metric","content:en-us:blog:how-gitlab-measures-red-team-impact-the-adoption-rate-metric.yml","How Gitlab Measures Red Team Impact The Adoption Rate Metric","en-us/blog/how-gitlab-measures-red-team-impact-the-adoption-rate-metric.yml","en-us/blog/how-gitlab-measures-red-team-impact-the-adoption-rate-metric",{"_path":2415,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2416,"content":2421,"config":2427,"_id":2429,"_type":14,"title":2430,"_source":16,"_file":2431,"_stem":2432,"_extension":19},"/en-us/blog/how-gitlab-supports-the-fedramp-authorization-journey",{"title":2417,"description":2418,"ogTitle":2417,"ogDescription":2418,"noIndex":6,"ogImage":1271,"ogUrl":2419,"ogSiteName":686,"ogType":687,"canonicalUrls":2419,"schema":2420},"How GitLab supports the FedRAMP authorization journey","This comprehensive guide dives into the FedRAMP certification process, explaining how GitLab offers guidance and best practices for configuration and compliance.","https://about.gitlab.com/blog/how-gitlab-supports-the-fedramp-authorization-journey","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How GitLab supports the FedRAMP authorization journey\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Christian Nnachi\"}],\n        \"datePublished\": \"2024-08-07\",\n      }",{"title":2417,"description":2418,"authors":2422,"heroImage":1271,"date":2424,"body":2425,"category":694,"tags":2426},[2423],"Christian Nnachi","2024-08-07","The Federal Risk and Authorization Management Program (FedRAMP) is a U.S. government program that standardizes security assessment, authorization, and continuous monitoring for cloud products and services. Achieving FedRAMP authorization allows cloud service providers (CSPs) to offer their services to federal agencies, ensuring that these services meet stringent security and privacy requirements.\n\nIn this article, you'll learn how to GitLab can help guide you on your FedRAMP authorization journey, including:\n* the key steps of the FedRAMP certification process\n* highlights of GitLab’s role in supporting FedRAMP requirements\n* best practices for configuration and compliance\n\nBy leveraging GitLab’s features and adhering to recommended practices, organizations can streamline their path to FedRAMP authorization and ensure secure and compliant software development.\n\n## Key requirements and compliance levels\n\nFedRAMP categorizes security requirements into [three levels based on the impact of data](https://www.fedramp.gov/understanding-baselines-and-impact-levels/) being handled:\n\n* **Low:** Impact on operations, assets, or individuals is limited.\n* **Moderate:** Impact on operations, assets, or individuals is serious.\n* **High:** Impact on operations, assets, or individuals is severe or catastrophic.\n\n## Security and privacy controls from NIST 800-53\n\nFedRAMP's security controls are derived from the [National Institute of Standards and Technology (NIST) Special Publication 800-53](https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final). Key areas include:\n\n* **Vulnerability scanning and patching SLAs:** Regular scanning and timely patching of vulnerabilities.\n* **Secure software supply chain:** Ensuring that the software and its components are secure.\n* **Change management:** Restricting unauthorized software or system changes through merge request (MR) approval rules.\n\n## Importance of FedRAMP for organizations\n\nFor CSPs, achieving FedRAMP authorization is crucial for doing business with federal agencies. Authorized services are listed on the [FedRAMP Marketplace](https://marketplace.fedramp.gov/products), enhancing their visibility and credibility.\n\n## Steps to achieve FedRAMP certification\n\nThe FedRAMP process is evolving, and a [new roadmap](https://www.fedramp.gov/2024-03-28-a-new-roadmap-for-fedramp/) has been introduced. To stay up to date on the latest changes, [subscribe to General Service Administration (GSA) list](https://public.govdelivery.com/accounts/USGSA/subscriber/new).\n\n### Walkthrough of the certification process\n\n#### 1\\. **Preparation and readiness**\n\n* **Preparation**\n  * Understand FedRAMP requirements and prepare documentation.\n* **Readiness assessment**\n  * CSPs can pursue the optional FedRAMP Ready designation by working with an accredited Third-Party Assessment Organization (3PAO). The 3PAO conducts a readiness assessment and documents the CSP's capability to meet federal security requirements in the Readiness Assessment Report (RAR).\n* **Pre-authorization**\n  * CSPs formalize partnerships with an agency as outlined in the FedRAMP Marketplace: Designations for Cloud Service Providers.\n  * CSPs prepare for the authorization process by making necessary technical and procedural adjustments to meet federal security requirements and prepare the required security deliverables for authorization.\n\n#### 2\\. **Authorization package submission and assessment**\n\n* **Authorization package submission**\n  * Historically: Submit the assessment package to the FedRAMP Joint Authorization Board (JAB) or a federal agency sponsor.\n  * [**New process**](https://www.fedramp.gov/2024-03-28-a-new-roadmap-for-fedramp/)**:** Submit to the FedRAMP Board within the GSA, replacing the JAB. The process integrates Agile principles and uses threat-based analysis for control selection and implementation.\n* **Full security assessment**\n  * The 3PAO conducts an independent audit of the CSP's system. Before this, the CSP should complete the System Security Plan (SSP) and have it reviewed and approved by the agency customer.\n  * The 3PAO develops the Security Assessment Plan (SAP) with input from the authorizing agency. After testing, the 3PAO creates a Security Assessment Report (SAR) detailing their findings and providing a recommendation for FedRAMP Authorization.\n* **Agency authorization process**\n  * The agency reviews the security authorization package, including the SAR, and may require CSP remediation.\n  * The agency performs a risk analysis, accepts the risk, and issues an Authority to Operate based on its risk tolerance, with the option to implement, document, and test customer-responsible controls either before or after the ATO issuance.\n\n#### 3\\. **Post-authorization and continuous monitoring**\n\n* **Continuous monitoring**\n  * The continuous monitoring phase involves post-authorization activities to maintain FedRAMP-compliant security authorization.\n* **New tool**\n  * [**automate.fedramp.gov**](https://www.fedramp.gov/2024-07-11-new-website-launch-automate-fedramp-gov/)**:** Provides detailed technical documentation, best practices, and guidance for creating and managing digital authorization packages with Open Security Controls Assessment Language ([OSCAL](https://pages.nist.gov/OSCAL/)). It supports a digital-first approach, offering faster documentation updates, enhanced user experience, and community collaboration.\n\nDetailed steps are available on the [FedRAMP Agency Authorization page](https://www.fedramp.gov/agency-authorization/). \n\n### Common challenges and pitfalls\n\n1. **Vulnerability management:** Ensuring timely and effective vulnerability management.\n2. **System boundaries:** Clearly defining and documenting system boundaries.\n3. **Software security practices:** Implementing and maintaining robust software security practices.\n4. **FIPS 140-2 cryptography:** Ensuring cryptographic modules are FIPS 140-2 compliant (details available in [GitLab's FIPS Compliance documentation](https://docs.gitlab.com/ee/development/fips_compliance.html)).\n\n## Role of self-managed GitLab in FedRAMP compliance\n\n### Supporting FedRAMP requirements\n\nSelf-managed GitLab can play a critical role in achieving FedRAMP compliance by providing tools and features that support secure code development and deployment within FedRAMP authorization boundaries.\n\n### Specific features of GitLab aligned with FedRAMP standards\n\n1\\. **Security configuration**\n\nYou can configure [CI/CD pipelines](https://docs.gitlab.com/ee/topics/build_your_application.html) to continuously test code while it ships and simultaneously enforce security policies. GitLab includes a suite of security tools that you can incorporate into the development of customer applications, including but not limited to:\n\n* [Security configuration](https://docs.gitlab.com/ee/user/application_security/configuration/index.html)\n* [Container scanning](https://docs.gitlab.com/ee/user/application_security/container_scanning/index.html)\n* [Dependency scanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/index.html)\n* [Static application security testing](https://docs.gitlab.com/ee/user/application_security/sast/index.html)\n* [Infrastructure as code (IaC) scanning](https://docs.gitlab.com/ee/user/application_security/iac_scanning/index.html)\n* [Secret detection](https://docs.gitlab.com/ee/user/application_security/secret_detection/index.html)\n* [Dynamic application security testing (DAST)](https://docs.gitlab.com/ee/user/application_security/dast/index.html)\n* [API fuzzing](https://docs.gitlab.com/ee/user/application_security/api_fuzzing/index.html)\n* [Coverage-guided fuzz testing](https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing/index.html)\n\n2\\. **Access control and authentication**\n\nAccess management in a GitLab deployment varies for each customer. GitLab offers extensive documentation on deployments using both identity providers and GitLab's native authentication configurations. It is crucial to evaluate your organization's specific requirements before deciding on an authentication approach for your GitLab instance.\n\n3\\. **[Identity providers](https://docs.gitlab.com/ee/security/hardening_nist_800_53.html#identity-providers)**\n\nTo comply with FedRAMP requirements, ensure your existing identity provider is FedRAMP-authorized and listed on the FedRAMP Marketplace, and for requirements like personal identity verification (PIV), use an identity provider rather than relying on native authentication in self-managed GitLab.\n\n4\\. **[Native GitLab user authentication configurations](https://docs.gitlab.com/ee/security/hardening_nist_800_53.html#native-gitlab-user-authentication-configurations)**\n\nGitLab enables administrators to monitor users with different levels of sensitivity and access requirements.\n\n5\\. [**Audits and accountability**](https://docs.gitlab.com/ee/administration/audit_event_streaming/)\n\nGitLab provides a wide array of security events and streaming capabilities for comprehensive logging and monitoring that can be routed to a Security Information and Event Management (SIEM) solution.\n\n* [Event types](https://docs.gitlab.com/ee/security/hardening_nist_800_53.html#event-types)\n\n6\\. **Incident response**\n\nAfter configuring audit events, it's crucial to monitor them. GitLab offers [tools](https://docs.gitlab.com/ee/operations/incident_management/index.html) for alert management, incident tracking, and status reporting through a centralized interface, allowing you to compile system alerts from SIEM or other security tools, triage incidents, and keep stakeholders informed.\n\n* [alerts](https://docs.gitlab.com/ee/operations/incident_management/alerts.html)\n* [incidents](https://docs.gitlab.com/ee/operations/incident_management/incidents.html)\n* [on-call schedules](https://docs.gitlab.com/ee/operations/incident_management/oncall_schedules.html)\n* [status page](https://docs.gitlab.com/ee/operations/incident_management/status_page.html)\n\n7\\. **Configuration management**\n\nAt its core, GitLab meets [configuration management](https://docs.gitlab.com/ee/security/hardening_nist_800_53.html#configuration-management-cm) needs with robust CI/CD pipelines, approval workflows, and change control, primarily using issues and MRs to manage changes.\n\n8\\. **Federal Information Processing Standard (FIPS) compliance**\n\nGitLab supports [FIPS compliance](https://docs.gitlab.com/ee/development/fips_compliance.html) by offering versions that use FIPS-validated cryptographic modules such as OpenSSL, BoringSSL, or other CMVP-validated modules. This ensures that cryptographic operations meet FIPS requirements, making it suitable for use in environments that require high levels of security compliance, such as those seeking FedRAMP authorization. Additionally, GitLab's documentation provides detailed instructions for installing and configuring FIPS-compliant deployments, including a hybrid approach using omnibus and cloud native components.\n\n9\\. [**NIST 800-53 R5 security and privacy controls management project template**](https://gitlab.com/gitlab-org/project-templates/nist_80053r5)\n\nThe project template helps track and manage compliance with NIST 800-53 R5 using GitLab issues, based on [NIST 800-53R5 specifications](https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final). It includes pre-configured issues, issue boards, and a notional example pipeline to run tests using OpenSCAP (OSCAP) and update issues with artifacts and labels, creating a controls management project within GitLab. This template centralizes compliance efforts, automates control testing, and facilitates a seamless workflow for both project teams and auditors.\n\n## Best practices for using GitLab in the FedRAMP process\n\n### Recommended configurations and setups\n\nTo align self-managed GitLab with NIST 800-53 controls and FedRAMP requirements, consider the following best practices:\n\n1. **Security hardening:** Follow GitLab’s [security hardening guidance](https://docs.gitlab.com/ee/security/hardening_nist_800_53.html).\n2. **Access control:** Implement role-based access control (RBAC) and enforce [the principle of least privilege](https://about.gitlab.com/blog/the-ultimate-guide-to-least-privilege-access-with-gitlab/).\n3. **CI/CD pipelines:** Configure pipelines to include security testing and approval stages.\n4. **Audit logging:** Enable comprehensive audit logging and integrate with a SIEM system.\n5. **Backup and recovery:** Establish robust backup and recovery processes.\n\n### NIST 800-53 compliance\n\nGitLab provides various compliance features to help automate critical controls and workflows. Administrators should work with customer solutions architects to configure GitLab instances to meet applicable [NIST 800-53 controls](https://docs.gitlab.com/ee/security/hardening_nist_800_53.html).\n\n## Start your FedRAMP compliance journey\n\nAchieving FedRAMP authorization is a complex but strategic process for CSPs looking to provide services to federal agencies. Self-managed GitLab offers a comprehensive suite of tools and features that can support this journey, ensuring secure and compliant software development and operations. By following best practices and leveraging GitLab’s capabilities, organizations can navigate the challenges of FedRAMP compliance and successfully achieve authorization.\n\n> Learn more about [GitLab's solutions for the public sector](https://about.gitlab.com/solutions/public-sector/).",[827,186,9],{"slug":2428,"featured":91,"template":698},"how-gitlab-supports-the-fedramp-authorization-journey","content:en-us:blog:how-gitlab-supports-the-fedramp-authorization-journey.yml","How Gitlab Supports The Fedramp Authorization Journey","en-us/blog/how-gitlab-supports-the-fedramp-authorization-journey.yml","en-us/blog/how-gitlab-supports-the-fedramp-authorization-journey",{"_path":2434,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2435,"content":2441,"config":2446,"_id":2448,"_type":14,"title":2449,"_source":16,"_file":2450,"_stem":2451,"_extension":19},"/en-us/blog/how-to-gitlab-single-sign-on-with-saml-scim-and-azures-entra-id",{"title":2436,"description":2437,"ogTitle":2436,"ogDescription":2437,"noIndex":6,"ogImage":2438,"ogUrl":2439,"ogSiteName":686,"ogType":687,"canonicalUrls":2439,"schema":2440},"How-to: GitLab Single Sign-on with SAML, SCIM, and Azure’s Entra ID","Follow this detailed walk-through of the configuration steps required to configure GitLab Single Sign-on, using Microsoft Azure’s Entra ID as the identity provider.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098047/Blog/Hero%20Images/Blog/Hero%20Images/AdobeStock_1097303277_6gTk7M1DNx0tFuovupVFB1_1750098046895.jpg","https://about.gitlab.com/blog/how-to-gitlab-single-sign-on-with-saml-scim-and-azures-entra-id","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How-to: GitLab Single Sign-on with SAML, SCIM, and Azure’s Entra ID\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Rob Jackson\"}],\n        \"datePublished\": \"2025-01-23\",\n      }",{"title":2436,"description":2437,"authors":2442,"heroImage":2438,"date":2311,"body":2444,"category":694,"tags":2445},[2443],"Rob Jackson","As organizations increase in size, it becomes increasingly difficult and critical to ensure that the right team members have access to the right groups and projects within their development platform. GitLab offers some powerful methods to manage user access, especially now with [custom roles](https://about.gitlab.com/blog/how-to-tailor-gitlab-access-with-custom-roles/), but performing this at scale through a point-and-click user interface can be frustrating. However, all is not lost. You can use Security Assertion Markup Language (SAML) and System for Cross-domain Identity Management (SCIM) as a solution. (There are moments where I’m grateful for acronyms.) \n\nI was researching this topic for a particular customer, and walking through the GitLab documentation on the capabilities, but I never felt like I truly understood the integration. As is often the case, especially when dealing with integrating components, the knowledge from experience far outweighs that gained from reading or watching. In that light, I wanted to share my steps along this path and invite you all to join me. All you need is a free trial of Microsoft Azure Entra ID and GitLab Premium with a top-level group on GitLab.com.  \n\n**Note:** This exercise produces a working integration, however, for production environments there may be necessary deviations. For example, the user account email for the identity provider (Entra ID in this case) will likely not match your GitLab account email. \n\n## Creating the application in Entra ID\n\nFirst, go to the Entra ID admin center. Within the **Applications** area, select **Enterprise Applications**. We’re going to create a new application, and then create our own application.\n\n![Entra ID application creation flow](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image13_aHR0cHM6_1750098073325.png)\n\n\u003Ccenter>\u003Ci>Figure 1: Entra ID application creation flow\u003C/i>\u003C/center>\u003Cbr>\n\nWith our new application created, we can start configuring the single sign-on (SSO) parameters for our application. For this task, you may want to have side-by-side browser windows. One window on your Entra ID application, and another window on the SAML settings for your GitLab group. Those settings are located under **Settings**, then SAML SSO on the left side of your GitLab window, as shown in Figure 2. If you don’t see this option, you aren’t in the top-level group, don’t have permission to configure SAML, or don’t have GitLab Premium enabled for that group.\n\n![GitLab SAML configuration](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image7_aHR0cHM6_1750098073326.png)\n\n\u003Ccenter>\u003Ci>Figure 2: GitLab SAML configuration\u003C/i>\u003C/center>\u003Cbr>\n\nWithin your Entra ID interface, select **Single sign-on** and click the SAML card.\n\n![Entra ID SAML configuration](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image24_aHR0cHM6_1750098073328.png)\n\n\u003Ccenter>\u003Ci>Figure 3: Entra ID SAML configuration\u003C/i>\u003C/center>\u003Cbr>\n\nWith the side-by-side view, the SAML configuration settings are on the left and the GitLab SSO settings on the right. \n\n![Side-by-side view of Entra ID and GitLab](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image16_aHR0cHM6_1750098073330.png)\n\n\u003Ccenter>\u003Ci>Figure 4: Side-by-side view of Entra ID and GitLab\u003C/i>\u003C/center>\u003Cbr>\n\nNow we can start copying and pasting parameters. Within the Entra ID interface, select **Edit** within the “Basic SAML Configuration” block. The parameter sources and destination are identified in the following table.\n\n| Source (GitLab) | Destination (Entra ID) |\n| :---------------- | :------: | \n| Identifier        |   Identifier (Entity ID)   | \n| Assertion consumer service URL |   Reply URL (Assertion Consumer Service URL)   | \n| GitLab single sign-on URL    |  Sign on URL (Optional)   | \n\n\u003Cbr>\nOnce completed, your side-by-side view should appear similar to the following (noting the URLs are unique to your environment).\u003Cbr>\n\n![Completed basic SAML SSO configuration](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image9_aHR0cHM6_1750098073332.png)\n\n\u003Ccenter>\u003Ci>Figure 5: Completed basic SAML SSO configuration\u003C/i>\u003C/center>\u003Cbr>\n\nClick **Save** within the Entra ID “Basic SML Configuration” window to save your hard work thus far. Note: You may need to click on the “X” in the upper right of the “Basic SAML Configuration” window if it doesn’t close automatically. \n\nAfter this window closes, you may get a popup to test single sign-on with your application. Select **No, I’ll test later**, because we still have more work to do (there is always more work to do). \n\n## Configuring attributes and claims\n\nWithin the Entra ID user interface, look for the section for “Attributes and Claims,” and click the **Edit** pencil icon. The first thing we want to do is modify the Unique User identifier (Name ID) value, so click on that row and set the Source attribute to **user.objectid**. Additionally, the Name identifier format must be updated, and set to **Persistent**.\n\n![Configuring attributes and claims](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image14_aHR0cHM6_1750098073333.png)\n\n\u003Ccenter>\u003Ci>Figure 6: Configuring attributes and claims\u003C/i>\u003C/center>\u003Cbr>\n\nSave that claim configuration. Now we have additional claims to configure, but there are only three that we need here. So, feel free to go wild and delete those default four items under **Additional claims**, or you can edit the existing ones to match the table below. Note that these values (specifically, the Name) are case sensitive. \n\u003Cbr>\n\n| Name | Namespace | Source Attribute |\n| :---------------- | :------: | :------: | \n|emailaddress |http://schemas.microsoft.com/ws/2008/06/identity/claims | user.otheremail |\n| NameID | http://schemas.microsoft.com/ws/2008/06/identity/claims |user.objectid |\n\n\u003Cbr>\n\nThe resulting claims configuration should appear as follows. Note the use of **otheremail** for the “emailaddress” attribute. This was necessary for me as my primary email addresses within Entra ID are not the addresses used on GitLab.com. If you recall, when I set up my “user,\" I modified the contact information to include my gitlab.com email address as one of my “Other emails.” \n\n![Configuring the claims](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image21_aHR0cHM6_1750098073335.png)  \n\n\u003Ccenter>\u003Ci>Figure 7: Configuring the claims\u003C/i>\u003C/center>\u003Cbr>\n\nWith your attributes configured, under the Advance settings, enable **Include attribute name format** setting.\n\n![Advanced claims configuration](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image8_aHR0cHM6_1750098073336.png)\n\n\u003Ccenter>\u003Ci>Figure 8: Advanced claims configuration\u003C/i>\u003C/center>\u003Cbr>\n\nYour \"Attributes and Claims\" window should now look similar to Figure 9 below.\n\n![Configured attributes and claims](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image18_aHR0cHM6_1750098073337.png)\n\n\u003Ccenter>\u003Ci>Figure 9: Configured attributes and claims\u003C/i>\u003C/center>\u003Cbr>\n\nIf you’re happy, or at least relatively content, with your configuration, click the “X” in the top right corner of the \"Attributes and Claims\" window to close it. \n\n## Configuring and assigning users\n\nNow that we have our application configured, we need to ensure that our users have been assigned to that application. I'll assume you’re working with a test instance that does not have the same email address as what is configured within your GitLab.com namespace. \n\nSo let’s go to the “Users and groups” within the Entra ID user interface for your configured application.\n\n![Managing application users and groups](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image17_aHR0cHM6_1750098073338.png)\n\n\u003Ccenter>\u003Ci>Figure 10: Managing application users and groups\u003C/i>\u003C/center>\u003Cbr>\n\nSelect **Add user/group**, and under the “Users and groups” where it says “None Selected,” click that text. Now you can select the user(s) to add to your application. These are the users that will be permitted to log into GitLab, authenticating themselves through Entra ID.\n\n![User selection](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image23_aHR0cHM6_1750098073339.png)\n\n\u003Ccenter>\u003Ci>Figure 11: User selection\u003C/i>\u003C/center>\u003Cbr>\n\nOnce selected, at the bottom of that page, click **Select**, and at the bottom of the next, select **Assign**. Now you should have a user assigned to your application.\n\n![User assigned to application](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image12_aHR0cHM6_1750098073340.png)\n\n\u003Ccenter>\u003Ci>Figure 12: User assigned to application\u003C/i>\u003C/center>\u003Cbr>\n\nNext, we need to ensure that the GitLab.com email address for that user is configured correctly. By clicking on the user itself, we can modify or configure some  additional information about that user. We can see below, the User principal name, which is based on an “onmicrosoft” domain. This is not the email address I have associated with my GitLab.com account. If you recall that we set the “Email address” attribute to “otheremail,” this is where we now configure that “other” email address. \n\n![User properties](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image20_aHR0cHM6_1750098073341.png)\n\n\u003Ccenter>\u003Ci>Figure 13: User properties\u003C/i>\u003C/center>\u003Cbr>\n\nClick the option to **Edit properties** for the user, and click on the **Contact Information** heading. Here we can add other emails – more specifically, the email address utilized for your GitLab.com account.  \n\n![Configuration of alternate email address](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image15_aHR0cHM6_1750098073342.png)\n\n\u003Ccenter>\u003Ci>Figure 14: Configuration of alternate email address\u003C/i>\u003C/center>\u003Cbr>\n\nThat should complete the configuration parameters that we need in Entra ID, but wait, there’s more. \n\nWithin the GitLab side now, you will need to configure a couple parameters. First, you might as well enable SAML for the group as that’s kind of a key piece here. GitLab offers some additional options to disable password authentication or enforce SSO to reduce the security risks within your application, but we’ll leave those unchecked for now. Similar to the table above, we’ll need a couple things from Entra ID to configure into GitLab. Please refer to the table below. \n\u003Cbr>\n\n| Source (Entra ID) | Destination (GitLab) | \n| :---------------- | :------: | \n|Login URL |Identity provider single sign-on URL |\n| Thumbprint | Certificate fingerprint|\n\n\u003Cbr>\n\n![GitLab SAML configuration from Entra ID](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image25_aHR0cHM6_1750098073343.png)\n\n\u003Ccenter>\u003Ci>Figure 15: GitLab SAML configuration from Entra ID\u003C/i>\u003C/center>\u003Cbr>\n\nLastly, you want to configure the default membership role for users logging in via SAML. Note that the access that you set for users here will cascade down to other groups and projects within your top-level group. Therefore, I would strongly recommend NOT setting this role to be “Owner.” Either “Guest” or “Minimal Access” would be acceptable options here, depending on the security posture of your organization. For more information about what these roles can and can not do, refer to the GitLab documentation on [Roles and Permissions](https://docs.gitlab.com/ee/user/permissions.html#roles). Now, save your work on the GitLab interface by clicking that beautiful blue **Save changes** button.\n\nWith your GitLab settings saved, you can now test your setup. I would encourage you to do this both through the “Verify SAML Configuration” on the GitLab system as well as with the Entra ID SSO \"Test\" button.\n\n## Troubleshooting SAML\n\nIn addition to the troubleshooting steps included within [GitLab documentation](https://docs.gitlab.com/ee/user/group/saml_sso/troubleshooting.html), I wanted to include a couple other items that I personally experienced. \n\nIf you get an error stating that the SAML reference did not contain an email address, check the Claim name for your email within the “Attributes and Claims” section within your Entra ID application. With GitLab 16.7, we added support for the “2008” attribute names, and at least for the email address setting, I found the default “xmlsoap” name for the email address claim to be a disappointing failure. \n\nAnother common error is “SAML Name ID and email address do not match your user account.” As you may suspect, this error is caused by a mismatch of the “NameID” and “emailaddress” attributes within the Entra ID application. This could be a misconfiguration of the “Attributes and Claims,” but it could also be that the properties of your test user don’t match your configuration. One helpful method to identify exactly what is coming through the SAML exchange is to use a SAML Tracer or SAML Message Decoder plugin with your web browser. \n\n## SCIM\n\nNow that you have SAML configured to enable users to log in via your Entra ID application, let’s make sure that people are assigned to the proper group(s) upon login. This can be incredibly helpful at scale, where instead of manually identifying which groups the particular users belong to, GitLab can learn this information from your identity application, Entra ID in this case. \n\nBecause SCIM utilizes groups to identify group membership, we need to create a group within Entra ID and add the relevant user(s) to the group. For this we’ll need the main administration menu for Entra ID. \n\n![Entra ID Group configuration](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image19_aHR0cHM6_1750098073344.png)\n\n\u003Ccenter>\u003Ci>Figure 16: Entra ID Group configuration\u003C/i>\u003C/center>\u003Cbr>\n\nWe’re going to create a new group and assign our user(s) to that group. So click **New group** and configure a new group, which only requires you to configure a “Group name.” I used the default group type of “Security.” Leave the “Membership type” as “Assigned.” From this window, we can also assign the members.\n\n![Creating a New Entra ID Group](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098073345.png)\n\n\u003Ccenter>\u003Ci>Figure 17: Creating a New Entra ID Group\u003C/i>\u003C/center>\u003Cbr>\n\nOnce you’ve added the member(s), click **Create** in the bottom of that window. With your group created, and the user(s) assigned to the group, we can configure SCIM.\n\nImmediately below the SAML configuration section within the GitLab UI, you’ll see the “SCIM Token” area. Here you can generate a new token, and copy the endpoint URL, both of which will be useful for the next steps. Note that if you forget or already have a SCIM token, it can be reset. \n\n![SCIM token and endpoint within GitLab](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image10_aHR0cHM6_1750098073345.png)\n\n\u003Ccenter>\u003Ci>Figure 18: SCIM token and endpoint within GitLab\u003C/i>\u003C/center>\u003Cbr>\n\nWith this information saved, return to your Entra ID application configuration. Within the left side menu, you’ll find the following: \n\n![Provisioning SCIM within Entra ID](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750098073346.png)\n\n\u003Ccenter>\u003Ci>Figure 19: Provisioning SCIM within Entra ID\u003C/i>\u003C/center>\u003Cbr>\n\nWithin the \"Provisioning\" section, click on **New Configuration**, which opens a new page where that token and URL from GitLab will be used. \n\n![New provisioning configuration](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image22_aHR0cHM6_1750098073348.png)\n\n\u003Ccenter>\u003Ci>Figure 20: New provisioning configuration\u003C/i>\u003C/center>\u003Cbr>\n\nFeel free to test the connection to ensure that you’ve configured the parameters properly. After testing, click on the **Create** button to establish the configuration and work on our mappings and settings. You may need to click the “X” in the top right corner of the panel to return to the overview configuration.\n\nExpand the “Mappings,” which includes two parameters; “Provision Microsoft Entra ID Groups” and “Provision Microsoft Entra ID Users.” SCIM group provisioning isn’t currently supported in GitLab, and although it doesn’t break the integration, keeping group provisioning enabled may cause negligible error messages. Therefore, we want to disable “Provision Microsoft Entra ID Groups,” so click that entry and set the “Enabled” field to “No.” \n\n![Provisioning attribute mapping](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image4_aHR0cHM6_1750098073349.png)\n\n\u003Ccenter>\u003Ci>Figure 21: Provisioning attribute mapping\u003C/i>\u003C/center>\u003Cbr>\n\nSave that configuration and select “Provision Microsoft Entra ID Users.” Validate that all three \"Target Object Actions\" are enabled, and then proceed to the “Attribute Mapping” section. Delete all existing mappings available to delete (I find this easier because attributes can’t be assigned twice), and then configure the Attribute Mappings per the following table:\n\n| customappsso Attribute (Destination) | Microsoft Entra ID Attribute (Source) | Matching Precedence | Mapping Type |\n| :---------------- | :------: | :------: | :------: | \n|externalID|objectId|1|Direct|\n|active|Switch([IsSoftDeleted], , \"False\", \"True\", \"True\", \"False\")| |Expression|\n|userName|mailNickname| |Direct|\n|name.formatted|displayName| |Direct|\n|Emails[type eq “other”].value|userPrincipalName||Direct|\n\n\u003Cbr>\n\n![Editing attributes](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image26_aHR0cHM6_1750098073349.png)\n\n\u003Ccenter>\u003Ci>Figure 22: Editing attributes\u003C/i>\u003C/center>\u003Cbr>\n\nAfter configuring all of the attribute mappings, the result should be similar to that found in Figure 22.\n\n![Completed attribute mapping configuration](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image5_aHR0cHM6_1750098073350.png)\n\n\u003Ccenter>\u003Ci>Figure 23: Completed attribute mapping configuration\u003C/i>\u003C/center>\u003Cbr>\n\nNote the use of the “other” email within the **customappssso** attribute. This relates back to the “other” email we configured for the user back in the Entra ID user properties. In a production situation, the emails for the SSO account and the email address for the account within GitLab should match. \n\nWith your mapping complete (congratulations, Ptolemy), there are some advanced configuration settings necessary. Underneath the \"Attribute Mappings,\" click the box for “Show advanced options.” Once this box is checked, a link called “Edit attribute list for customappsso” is revealed.\n\n![Advanced attribute configuration](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image6_aHR0cHM6_1750098073351.png)\n\n\u003Ccenter>\u003Ci>Figure 24: Advanced attribute configuration\u003C/i>\u003C/center>\u003Cbr>\n\nClick that link, and ensure that the Name “ID” is both “Primary Key” and “Required,” and that “externalID” is also “Required.” These attributes both refer to a unique user ID generated by Entra ID. However, although the “id” itself is required, it is not consistently provided within the API calls. Therefore, GitLab relies on the “externalID” to ensure the proper connection between the Entra ID and GitLab user accounts. \n\n![Required attribute list](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098073351.png)\n\n\u003Ccenter>\u003Ci>Figure 25: Required attribute list\u003C/i>\u003C/center>\u003Cbr>\n\nSave these settings, and then close the “Attribute Mapping” page with the “X” in the top right of the window. Return to the \"Application Provisioning\" section and click **Start provisioning**. \n\nWithin GitLab, we need to configure the association between the group we configured within Entra ID and the level of access we want those users to have within the GitLab top-level group. Note that this association can be configured on each sub-group within GitLab for more extensive provisioning, but within GitLab, permissions flow downhill. Whatever permission you set for a user at a top-level group, or sub-group, will cascade down to all projects and groups contained therein. \n\nWithin the \"Settings\" portion of the GitLab menu, select **SAML Group Links**. Here is where you’ll configure the group name and determine what access level, or role, members of the Entra ID Group will have within this particular GitLab Group.\n\n![GitLab SAML Group link](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image27_aHR0cHM6_1750098073352.png)\n\n\u003Ccenter>\u003Ci>Figure 26: GitLab SAML Group link\u003C/i>\u003C/center>\u003Cbr>\n\nAs shown in Figure 26, I’ve configured my membership to The Academy such that any users within the dev-security group from Entra ID  will be granted Developer access. Note that this is a slight variation of what a typical production environment would look like. In most instances, the user account within the identity provider (Entra ID, in this case) would match the user’s corporate account email (and we wouldn’t require “other” emails). When configured properly, if the user does not already have an account on GitLab, one will be created for them tied to their SSO account. \n\n![GitLab SSO tutorial - image11](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098073/Blog/Content%20Images/Blog/Content%20Images/image11_aHR0cHM6_1750098073352.png)\n\n\u003Ccenter>\u003Ci>Figure 27: SAML Group Links configured\u003C/i>\u003C/center>\u003Cbr>\n\nNow that you’ve completed the configuration, give it a try! From another browser, preferably in private mode to ignore any cookies or other yummy artifacts, paste the link for the GitLab SSO URL found in the GitLab SAML configurations. You should be prompted to log in with your Entra ID credentials and gain the proper access to your GitLab group! \n\nCongratulations, you’ve made it! I hope you’ve learned from and appreciate the work here, and we can all rejoice in the fact that the users within the Play-Dough app can now all properly authenticate, with the right permissions, to The Academy!\n\n> Don't have a GitLab account? [Sign up for a free trial today](https://about.gitlab.com/free-trial/devsecops/).\n\n## Read more\n- [The ultimate guide to enabling SAML and SSO on GitLab.com](https://about.gitlab.com/blog/the-ultimate-guide-to-enabling-saml/)\n- [SAML SSO for GitLab.com groups documentation](https://docs.gitlab.com/ee/user/group/saml_sso/)",[827,694,496,9,1259],{"slug":2447,"featured":6,"template":698},"how-to-gitlab-single-sign-on-with-saml-scim-and-azures-entra-id","content:en-us:blog:how-to-gitlab-single-sign-on-with-saml-scim-and-azures-entra-id.yml","How To Gitlab Single Sign On With Saml Scim And Azures Entra Id","en-us/blog/how-to-gitlab-single-sign-on-with-saml-scim-and-azures-entra-id.yml","en-us/blog/how-to-gitlab-single-sign-on-with-saml-scim-and-azures-entra-id",{"_path":2453,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2454,"content":2460,"config":2465,"_id":2467,"_type":14,"title":2468,"_source":16,"_file":2469,"_stem":2470,"_extension":19},"/en-us/blog/how-to-harden-your-self-managed-gitlab-instance",{"title":2455,"description":2456,"ogTitle":2455,"ogDescription":2456,"noIndex":6,"ogImage":2457,"ogUrl":2458,"ogSiteName":686,"ogType":687,"canonicalUrls":2458,"schema":2459},"How to harden your self-managed GitLab instance","Learn seven easy steps to ensure your self-managed GitLab instance is as secure as possible.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664923/Blog/Hero%20Images/security-checklist.png","https://about.gitlab.com/blog/how-to-harden-your-self-managed-gitlab-instance","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to harden your self-managed GitLab instance\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Ayoub Fandi\"}],\n        \"datePublished\": \"2023-05-23\",\n      }",{"title":2455,"description":2456,"authors":2461,"heroImage":2457,"date":2462,"body":2463,"category":909,"tags":2464},[778],"2023-05-23","\n\"You are as secure as your weakest link\" is a well-understood phrase. If attackers find their way in, they will exploit any gaps in your security configurations. Hardening — the process of turning off unused features and making adjustments to settings that have security implications — is critical to limit your attack surface and reduce potential attack vectors.\n\nHardening ensures that your application (in this case GitLab) is as secure as it can be. The goal is simple: minimize risk while still preserving enough functionality for users to remain as productive as possible.\n\n## Guiding principles\nThese principles should guide the way you approach hardening. The security activities in the checklist below will tie back to one or another of these principles.\n\n### Layered security\nThe idea behind this is simple. If there are two ways to implement security, both ways should be implemented instead of just one. You can try to combine as many methods as possible. \n\nFor instance, if you are trying to secure access to your service, you could combine a complex password with hardware tokens and multifactor authentication. This approach is also called defense-in-depth.\n\n### No security through obscurity\nThe idea of hiding things works in many cases, but not so in the information security world. The premise that if something is hidden then it is more secure isn’t a viable approach today. \n\nCurrent scanning capabilities available to attackers shatter through obscurity. It is very easy for anyone to scan for open ports on a system. If you’ve swapped the SSH port TCP 22 to a different port, it would be picked up by a network scanning tool such as Nmap. \n\nAs GitLab is committed to transparency and open source, our approach is at odds with security through obscurity. The goal of security is to remove any security through obscurity. Our documentation is available to all and security best practices are clearly labeled and detailed.\n\n### Reducing the attack surface\nGitLab comprises numerous components, services, and dependencies. A critical aspect of security is: The more components you have, the more entryways attackers have.\n\nA good rule to keep in mind is to always disable services that you do not need to run the application. If there are features that aren’t used, disabling the related services will reduce the potential attack surface and make you more secure.\n\n## 7 steps to secure your self-managed instance\nLet’s go through seven easy steps to quickly harden your self-managed instance. These quick wins are great first steps towards securing your installation. Of course, refer to the [documentation](https://docs.gitlab.com/ee/security/) for additional details and further guidance on each section.\n\n### 1. Enable multi-factor authentication\n**Admin > Settings > General > Sign-in restrictions**\n\nEnsure that the checkbox next to _Two-factor authentication_ (2FA) is **checked**. The default setting for _Two-factor grace period_ is 48 hours. Adjust it to a lower value, such as **8 hours**.\n\nEnsure the checkbox next to _Enable admin mode_ is **checked** so that _Admin Mode_ is **active**. Users with Admin access will have to use additional authentication to perform administrative tasks. With 2FA enabled, this will require additional 2FA authentication by the user.\n\nFor more detailed information, refer to the documentation on [sign-in restrictions](https://docs.gitlab.com/ee/administration/settings/sign_in_restrictions.html).\n\n### 2. Enforce additional sign-up checks\n**Admin > Settings > General > Sign-up restrictions**\n\nNext to _Sign-up enabled_ ensure the checkbox is **unchecked**.\n\nUnder _Email confirmation settings_ ensure that **Hard** is selected. This will require the user to verify their email address during the sign-up process before their account is allowed access.\n\nThe _Minimum password length (number of characters)_ default setting of 12 characters is fine if additional authentication techniques are enforced. Options available for password complexity include _Require numbers_, _Require uppercase letters_, _Require lowercase letters_, and _Require symbols_. Check these boxes depending on your internal password standard (also check out [NIST SP 800-63B](https://pages.nist.gov/800-63-3/sp800-63b.html)).\n\nIf all users' email addresses are under a single domain (e.g., example.com), consider **adding it** to the _Allowed domains for sign-ups_. This will prevent those with email addresses associated with other domains from signing up.\nFor more detailed information, refer to the documentation on [sign-up restrictions](https://docs.gitlab.com/ee/administration/settings/sign_up_restrictions.html).\n\n### 3. Limit public visibility of your groups and projects\n**Admin > Settings > General > Visibility and access control**\n\nThe _Default project visibility_ and _Default group visibility_ for any newly created project or group should be set to **Private** by default. Only users that are granted specific access to a project or group will be able to access these resources. This can be adjusted later if necessary or when creating a new project or group. This ensures the default mode is secure to prevent accidental disclosure of information.\n\nFor more details on Visibility and access control [refer to the documentation](https://docs.gitlab.com/ee/administration/settings/visibility_and_access_controls.html).\n\n### 4. Harden your SSH settings\n**Admin > Settings > General > Visibility and access control**\n\nTypically, under _Enabled Git access protocols_ it will be set to _Both SSH and HTTP(S)_. If one of the Git protocols is not in use by your users, set it to **either** _Only SSH_ or _Only HTTP(S)_ accordingly. This will reduce the attack surface by limiting possibilities of compromise through an unused protocol.\nFor SSH key types, the most recommended algorithms to use are, in order: \n1. ED25519\n1. RSA \n1. ECDSA\n\nWhen configuring default types and lengths for SSH keys, keep in mind the list above.\n\nSpecific details on SSH settings can be found [here](https://docs.gitlab.com/ee/security/ssh_keys_restrictions.html) and [here](https://docs.gitlab.com/ee/administration/settings/visibility_and_access_controls.html#configure-enabled-git-access-protocols) for Git Access protocols.\n\n### 5. Review the account and limit settings\n**Admin > Settings > General > Account and limit settings**\n\nThis section allows you to limit the size of attachments, pushes, exports, imports, or repositories. As the specific size (in MB) will be tailored to your needs, review these settings and **set limits** in line with your internal policies.\n**Session duration for users** (in minutes) and **lifetime of SSH keys and all access tokens** (in days) can also be configured. Ensure the durations are in accordance with your internal policies and security best practices.\n\nReview the [documentation](https://docs.gitlab.com/ee/administration/settings/account_and_limit_settings.html) and apply changes that enforce your own policies.\n\n### 6. Secure your CI secrets\n**Admin > Settings > CI**\n\nPasswords, tokens, keys, and other secrets that require any level of protection should never be stored in plaintext. Instead, some type of **encrypted container technology (Secrets Manager)** should be implemented, such as GCP's Secret Manager, AWS Key Management Service (KMS), or HashiCorp Vault. For self-managed and standalone instances, HashiCorp Vault is **recommended**, and many GitLab features can take advantage of Vault and are well described in the [documentation](https://docs.gitlab.com/search/?query=vault).\n\nFor external communications, ensure any connectivity with external hosts in your CI/CD process is using encrypted channels. The use of TLS 1.2 or above is highly recommended and where possible mutual TLS will help things considerably.\nFor details on the use of external secrets for your CI/CD pipeline, check [here](https://docs.gitlab.com/ee/ci/secrets/) for actual examples and configuration guides.\n\n### 7. Protect your pipelines for all branches\n**Admin > Settings > CI**\n\nPipelines are a part of jobs that execute steps in stages to automate tasks on behalf of the users of a project. They are a central component of CI/CD.\nBy default, only the default branch gets a protected pipeline. Configure your other branches with the same level of security by following [these simple steps](https://docs.gitlab.com/ee/user/project/protected_branches.html#configure-a-protected-branch). This considerably hardens your pipelines.\n\nThe security features enabled by default on protected pipelines are listed in our [documentation](https://docs.gitlab.com/ee/ci/pipelines/#pipeline-security-on-protected-branches).\n\nOnce the pipeline has run, the code will be deployed in an environment. To limit interactions with that environment and to protect it from unauthorized users, you can set your key environments as protected.\n\nPrerequisites and full process are available in the [documentation](https://docs.gitlab.com/ee/ci/environments/protected_environments.html).\n\n### Learn more \nThis is a high-level overview of the different areas to focus on when hardening your self-managed GitLab instance. A blog post can’t include every single security recommendation. That’s why we maintain detailed [security documentation](https://docs.gitlab.com/ee/security/) on how to secure your installation. \n\nPlease refer to the documentation as the single source of truth on hardening. Hopefully, with the help of the action items highlighted above, you’ll harden your self-managed GitLab instance while preserving agility and speed.\n\nIf you want to learn more about how we do security **at GitLab**, review the [security section](https://about.gitlab.com/handbook/security/) of the handbook.\n",[694,827,9],{"slug":2466,"featured":6,"template":698},"how-to-harden-your-self-managed-gitlab-instance","content:en-us:blog:how-to-harden-your-self-managed-gitlab-instance.yml","How To Harden Your Self Managed Gitlab Instance","en-us/blog/how-to-harden-your-self-managed-gitlab-instance.yml","en-us/blog/how-to-harden-your-self-managed-gitlab-instance",{"_path":2472,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2473,"content":2478,"config":2483,"_id":2485,"_type":14,"title":2486,"_source":16,"_file":2487,"_stem":2488,"_extension":19},"/en-us/blog/how-to-successfully-deliver-your-software-development-roadmap",{"title":2474,"description":2475,"ogTitle":2474,"ogDescription":2475,"noIndex":6,"ogImage":2091,"ogUrl":2476,"ogSiteName":686,"ogType":687,"canonicalUrls":2476,"schema":2477},"How to successfully deliver your software development roadmap","Here are three common blockers and how to overcome them to fully realize the ROI of a DevSecOps platform investment.","https://about.gitlab.com/blog/how-to-successfully-deliver-your-software-development-roadmap","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to successfully deliver your software development roadmap\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David DeSanto, Chief Product Officer, GitLab\"}],\n        \"datePublished\": \"2024-04-04\",\n      }",{"title":2474,"description":2475,"authors":2479,"heroImage":2091,"date":2480,"body":2481,"category":10,"tags":2482},[1905],"2024-04-04","2024 is shaping up to be the year of DevSecOps, where more organizations realize the full potential of blending development, security, and operations through the adoption of a comprehensive platform. This is when teams will move beyond using just source code management (SCM) and tap into all the [AI-powered features](https://about.gitlab.com/topics/devops/the-role-of-ai-in-devops/) available across the software development lifecycle (SDLC), delivering better, more secure software faster. But first organizations have to knock down the blockers that can get in the way of successful [DevSecOps](https://about.gitlab.com/topics/devsecops/) adoption.\n\nIn talking to customers at organizations of all sizes, I've heard three main blockers:\n* The potential of AI is believable, but right now it seems limited to code creation and that has limited impact as there is more to the SDLC.\n* A platform seems like a great idea, but forcing my development, security, and operations team to give up their preferred tools all at once will undoubtedly cause a revolt. Yet, without everyone on the same platform, the investment is hard to justify.\n* Regulations and compliance makes it difficult to leverage a DevSecOps SaaS solution, and being on a multi-tenant solution is a non-starter for us as we are in a highly regulated industry. However, the overhead of self-hosting a DevSecOps platform is becoming untenable at our scale.\n\nWhile legitimate concerns, these blockers can be eliminated by combining DevSecOps practices and a platform approach. \"Making sure that we spend our money wisely is very, very important. GitLab allowed us to reduce our costs and centralize our work in one place. It’s been money well spent,\" says Andy Chow, Technology Chief of Staff at global fintech company Airwallex.\n\nLet's dig deeper into each blocker and see how it is resolved with a DevSecOps platform.\n\n> Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Watch today!](https://about.gitlab.com/seventeen/)\n\n### AI is not limited: It is having real impact across the SDLC\n\nWe know that AI is already improving the developer experience but there is so much more that AI can do across the entire SDLC. With AI, organizations can unburden development, security, and operations teams from tedious tasks by taking advantage of the efficiencies that AI provides. For instance, users can access summaries of comments in merge requests, have tests generated, refactor sections of code, and perform other time-saving actions.\n\nThat's why with [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our suite of AI-powered workflows, we focus on more than just code creation — after all, [code creation only accounts for 25% of a developer's time](https://about.gitlab.com/blog/gitlab-global-devsecops-ai-report/). There is so much more that happens in the SDLC where AI can add efficiency. For instance, development, security, and operations teams that use AI-powered capabilities, such as Vulnerability Remediation and Root Cause Analysis, share that they can find and resolve vulnerabilities earlier and identify CI/CD pipeline failures faster and in a more collaborative manner.\n\n### Forget one-size-fits all, migrate your way\n\nRealizing the benefit of a DevSecOps platform is not a one-size-fits-all. You can customize your deployment to fit your organization's needs and where you are in your digital transformation journey — choosing one team at a time to adopt the platform or a full cutover. I have advice, though: Commit to using more than just source code management. A DevSecOps platform is a robust solution that includes enterprise agile planning, CI/CD, security and compliance, value stream analytics, and more. Also, make sure that as you deploy your platform, your users agree to get familiar with its range of capabilities — and not still maintain [a complex toolchain](https://about.gitlab.com/blog/battling-toolchain-technical-debt/).\n\nThe way to extract the most ROI and satisfaction from your migration is to show users how to get the functionality they had in their other tools from within the DevSecOps platform. To that end, we've increased our resources to support you. From [in-depth tutorials](https://about.gitlab.com/blog/tags/tutorial/) to [clear reference architectures](https://docs.gitlab.com/ee/administration/reference_architectures/), we have a vast library of content (including videos) for you to draw upon to help your users acclimate to and thrive in the DevSecOps environment. \n\nWe've also made it easier to onboarding teams, with capabilities like [remote development environments](https://about.gitlab.com/blog/quick-start-guide-for-gitlab-workspaces/), enabling organizations to reduce adoption friction. In fact, as more teams within your organization adopt GitLab, consider expanding access for other critical functions that contribute to delivering software value such as Finance, Legal, and Marketing teams. The power of a DevSecOps platform is giving everyone visibility into the SDLC which drives better collaboration, improves planning, reduces security risk, improves team velocity, and leads to faster time-to-value. This means your teams are happier and so are the users of the applications you build, secure, and deploy using GitLab.\n\n> Read how the U.S. Navy's Black Pearl [sped up onboarding using GitLab](https://about.gitlab.com/blog/u-s-navy-black-pearl-lessons-in-championing-devsecops/).\n\n**Note:** GitLab doesn't have to be introduced to the organization by the development team. For instance, if security teams want vulnerabilities identified and mitigated earlier in the lifecycle or increased compliance via security scanning, they can recommend that developers use the DevSecOps platform. [Read how U.K. retailer Dunelm made this happen](https://about.gitlab.com/customers/dunelm/).\n\n### Multi-tenancy is just one option; single-tenancy can address regulatory requirements\n\nKeeping software up-to-date and secure while maintaining compliance with strict regulations can make self-hosting a challenge. In June 2023, we launched [GitLab Dedicated](https://about.gitlab.com/dedicated/), our single-tenant SaaS solution, into general availability to address the needs of organizations in highly regulated industries like finance and healthcare, and in highly regulated geographies such as the European Union. GitLab Dedicated provides the secure environment organizations need for regulatory compliance, including control over data residency and isolation, while removing the overhead of self-hosting.\n\nDedicated customers are upgraded automatically every month, which means they have all of the benefits without the administration overhead. Furthermore, GitLab Dedicated comes with [GitLab Ultimate](https://about.gitlab.com/pricing/ultimate/), enabling organizations to ship secure software faster with built-in compliance visibility and controls as well as advanced security scanning capabilities.\n\n> Learn the [origins of GitLab Dedicated](https://about.gitlab.com/blog/building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated/) and how it has grown into the solution highly regulated organizations need.\n\n### Try GitLab today\n\nAs you proceed with your software development roadmap for 2024 (and beyond), consider what an AI-powered DevSecOps platform could do for your organization. Also keep an eye on [our Direction page](https://about.gitlab.com/direction/#fy25-rd-investment-themes) to learn about what’s coming next and [our monthly release posts](https://about.gitlab.com/blog/categories/devsecops-platform/) to learn about the latest and greatest available.\n\n> Start your trial of [GitLab Duo Pro](https://about.gitlab.com/gitlab-duo/#free-trial) or [GitLab Ultimate](https://gitlab.com/-/trials/new) for free today.\n",[717,9,496,694],{"slug":2484,"featured":91,"template":698},"how-to-successfully-deliver-your-software-development-roadmap","content:en-us:blog:how-to-successfully-deliver-your-software-development-roadmap.yml","How To Successfully Deliver Your Software Development Roadmap","en-us/blog/how-to-successfully-deliver-your-software-development-roadmap.yml","en-us/blog/how-to-successfully-deliver-your-software-development-roadmap",{"_path":2490,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2491,"content":2497,"config":2504,"_id":2506,"_type":14,"title":2507,"_source":16,"_file":2508,"_stem":2509,"_extension":19},"/en-us/blog/how-to-tailor-gitlab-access-with-custom-roles",{"title":2492,"description":2493,"ogTitle":2492,"ogDescription":2493,"noIndex":6,"ogImage":2494,"ogUrl":2495,"ogSiteName":686,"ogType":687,"canonicalUrls":2495,"schema":2496},"How to tailor GitLab access with custom roles","Find out the current capabilities of custom roles and what's to come, including initial grouping of permissions and templating from default roles.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098975/Blog/Hero%20Images/Blog/Hero%20Images/AdobeStock_729993502_1Xe0pzHPX4C3b1Ycs2q7RP_1750098974565.jpg","https://about.gitlab.com/blog/how-to-tailor-gitlab-access-with-custom-roles","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to tailor GitLab access with custom roles\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Joe Randazzo\"},{\"@type\":\"Person\",\"name\":\"Hannah Sutor\"}],\n        \"datePublished\": \"2024-02-13\",\n      }",{"title":2492,"description":2493,"authors":2498,"heroImage":2494,"date":2501,"body":2502,"category":10,"tags":2503},[2499,2500],"Joe Randazzo","Hannah Sutor","2024-02-13","At GitLab, we knew we had a big problem to solve. Our existing, default user roles were becoming roadblocks for our customers. The default roles, such as Guest, Reporter, Developer, Maintainer, and Owner, offer a predefined set of permissions that cannot be customized. Customers were forced to fit their specific needs into the existing roles, leading to either overly permissive access, which is a security risk, or under-privileged access, which required administrator overhead to temporarily elevate privileges of a user in order to perform a task, and remember to move them back down to their normal role afterwards.\n\nIn 15.9, we released our [first iteration for customizable roles](https://about.gitlab.com/blog/expanding-guest-capabilities-in-gitlab-ultimate/) within GitLab. It allowed customers to do one simple thing: Give the Guest user the ability to view code, without consuming a seat. Our hope was to give our customers the ability to add more privilege to the Guest role, if they so desired, while retaining the benefit of free Guest users with an Ultimate subscription.\n\nOur MVC was released almost a year ago now, so we wanted to provide an update on the progress we’ve made with customizable roles and an idea of where we are headed.\n\n![Custom roles - image 1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098994/Blog/Content%20Images/Blog/Content%20Images/create_role_output__2__aHR0cHM6_1750098994380.gif)\n\n![Custom roles - image 2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098994/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098994380.gif)\n\n## Looking at the next iteration of custom roles\n\nAs we build toward the next iteration of [custom roles](https://docs.gitlab.com/ee/user/custom_roles.html) and permissions, we have gathered a lot of feedback from the MVC. Two common themes that have been uncovered are:\n- reducing privilege of Developer, Maintainer, and Owner roles\n- a wide range of access permutations\n\nHere's how we plan to address these challenges.\n\n### Consistent CRUD model\n\nIf you have designed role-based access control (RBAC) in Google Cloud Platform (GCP) or Kubernetes, you may have appreciated the predictable permission verbs on resource access. As we continue to build out the next groupings of permissions for custom roles, the permissions will follow a consistent Create, Read, Update, and Delete (CRUD) model so you can predictably design your resource access within your organization.\n\nIf we examine the table below, “Manage” would be given to select few in the department or organization, whereas \"Write\" and \"View\" would be a common contributor to that resource.\n\n| Permission    | Description     |\n| ---------- | ---------- |\n| Manage       | Full CRUD operations on resources. Plus configuring the settings of the resource. *Assumes Write/View/Delete* |\n| Write       | Add or update the resource. *Assumes View*     |\n| View       | View the resource      |\n| Delete      | Delete the resource. *Assumes View*      |\n\n\u003Cp>\u003C/p>\n\nBelow is a concrete example of permissions related to registries. While this table is coarse-grained as this groups all registry types together at first, this can become fine-grained over time by pulling out each registry type as requested.\n\n\u003Cp>\u003C/p>\n\n| Permission    | Description     |\n| ---------- | ---------- |\n| Manage       | CRUD operations on objects, including Registries, Proxy, Cleanup Policies, along with managing the settings      |\n| Write       | Ability to push a container, package, or terraform module to registry    |\n| View       | Ability to view, retrieve, and pull registry objects and metadata on repositories and images      |\n| Delete      | Ability to delete registry objects and metadata      |\n\n### Remove default role dependency\n\nDuring the custom role creation process, starting with a base default role can be a quick way to add permissions, but it’s limiting when reducing only one or two permissions from Maintainer or Owner. The next iteration will allow you to build your own custom role without the predefined permissions of default roles allowing for maximum flexibility.\n\n### Build your own role\n\nBuilding a custom role in a system should account for the number of permutations while isolating access for those in strict environments. As we group these resources, we are factoring in that there are a wide range of themes including project management, development, security, and operations.\n\nBelow is a sample of [groupings](https://gitlab.com/jrandazzo/build-your-own-permissions-survey) with a permission selection that could apply to a developer. These resource groups may become finer over time based on requests.\n\n![custom roles - image 3](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098994/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750098994382.png)\n\n### Building a role from a template\n\nYou may have experienced building permission sets as a starting point to simplify the assignment of user access. As you build out a custom role, you could start with a template that copies predefined permissions from a default role or specific user types such as a Project Manager.\n\n## How to contribute\n\nWe value your feedback and there are multiple ways to contribute:\n- We created a “build your own role” survey to understand how an organization would create a least privilege user in GitLab. Here is a [survey link](https://forms.gle/ucx9CNqqUbVVyAse9) to validate our initial assumptions on permission groupings.\n- Would you like to submit ideas or share feedback based on custom roles? Here is the [feedback issue](https://gitlab.com/gitlab-org/gitlab/-/issues/439638).\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[848,694,9,719],{"slug":2505,"featured":91,"template":698},"how-to-tailor-gitlab-access-with-custom-roles","content:en-us:blog:how-to-tailor-gitlab-access-with-custom-roles.yml","How To Tailor Gitlab Access With Custom Roles","en-us/blog/how-to-tailor-gitlab-access-with-custom-roles.yml","en-us/blog/how-to-tailor-gitlab-access-with-custom-roles",{"_path":2511,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2512,"content":2518,"config":2524,"_id":2526,"_type":14,"title":2527,"_source":16,"_file":2528,"_stem":2529,"_extension":19},"/en-us/blog/how-we-designed-the-gitlab-reference-architectures",{"title":2513,"description":2514,"ogTitle":2513,"ogDescription":2514,"noIndex":6,"ogImage":2515,"ogUrl":2516,"ogSiteName":686,"ogType":687,"canonicalUrls":2516,"schema":2517},"How we designed the GitLab Reference Architectures","Take a look back with us as we dive into our Reference Architectures design journey to help users easily deploy GitLab at scale. Learn our goals, process, and what's happened in the five years since.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098651/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%282%29_52vS9ne2Hu3TElOeHep0AF_1750098651525.png","https://about.gitlab.com/blog/how-we-designed-the-gitlab-reference-architectures","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How we designed the GitLab Reference Architectures\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Grant Young\"}],\n        \"datePublished\": \"2024-10-02\",\n      }",{"title":2513,"description":2514,"authors":2519,"heroImage":2515,"date":2521,"body":2522,"category":909,"tags":2523},[2520],"Grant Young","2024-10-02","We introduced the first [GitLab Reference Architectures](https://docs.gitlab.com/ee/administration/reference_architectures) five years ago. Originally developed as a partnership between the GitLab Test Platform (formally Quality Engineering) and Support teams, along with other contributors, these architectures aim to provide scalable and elastic starting points to deploy GitLab at scale, tailored to an organization's target load.\n\nSince their debut, we've been thrilled to see the impact these architectures have had on our customers as they navigate their DevSecOps journey. We continue to iterate, expand, and refine the architectures, reflecting our commitment to providing you with the latest, best-in-class guidance on deploying, scaling, and maintaining your GitLab environments.\n\nIn recognition of the five-year milestone, here is a peek behind the curtain on _how_ we designed the Reference Architectures and how that design still applies today.\n\n## The problem\n\nBefore introducing the Reference Architectures, we frequently heard from our customers about the hurdles they faced when deploying GitLab at scale to meet their performance and availability goals.\n\nWhile every GitLab environment can be considered a little unique because of the need to meet a customer's own requirements, we recognized from running GitLab.com, as well as from our larger customers, that there were common fundamentals to deploying GitLab at scale that were worth sharing. Our objective was to address customer needs while promoting deployment best practices to reduce drift and increase alignment.\n\nSimultaneously, we wanted to significantly expand our performance testing efforts. The goals of this expansion were to provide our engineering teams with a deeper understanding of performance bottlenecks, to drive improvements in GitLab's performance, and to continuously test the application moving forward to ensure it remained performant. However, to conduct meaningful performance tests, we needed a standardized GitLab environment design capable of handling the target loads.\n\nEnter the Reference Architectures.\n\n## The goals\n\nWith the need for a common architecture clear, we turned next to set the goals of this initiative, which ultimately became the following:\n\n- Performance: Ensure the architecture can handle the target load efficiently.\n- Availability: Maximize uptime and reliability wherever possible.\n- Scalability and elasticity: Ensure the architecture is scalable and elastic to meet individual customer needs.\n- Cost-effectiveness: Optimize resource allocation to avoid unnecessary expenses.\n- Maintainability: Make the architecture deployment and management as straightforward as possible with standardized configurations.\n\nIt's crucial to note that these goals were not in order and they are goals we stay true to today.\n\n## The process\n\nOnce the goals were set, we faced the challenge of designing an architecture, validating it, and making sure that it was fit for purpose and met those goals.\n\nThe process itself was relatively simple in design:\n\n- Gather metrics on existing environments and the loads they were able to handle.\n- Define a prototype architecture based on these metrics.\n- Build and test the environment to validate.\n- Adjust the environment iteratively based on the test results and metrics until we had a validated architecture that met the goals.\n\nWhile simple in design, this, of course, was not the case in practice so we got to work.\n\nFirst, we collected and reviewed the data. To that end, we reviewed metrics and logging data from GitLab.com as well as several participating large customers to correlate the environment sizes deployed to the load they were handling. To achieve this, we needed an objective and quantifiable way to measure that load across any environment, and for that we used **Requests per Seconds (RPS)**. With RPS we could see the concurrent load each environment handled and correlate this to the user count accordingly. Specifically, a user count would correlate to the full manual and automated load (such as continuous integration). From that data, we were able to correlate this across several environment sizes and start to pick out common patterns for the architectures.\n\nNext, we started with a prototype architecture that aimed to meet the goals while cross-referencing with the data we collected. In fact, we actually started this step in conjunction with the first step initially as we had a good enough idea of where to start: Taking the fundamental GitLab.com design and scaling it down for individual customer loads in cost-effective ways. This allowed us to start performance testing the prototype with the data we were analyzing to corroborate accordingly. After quite a few iterations, we had a starting point for our prototype architecture.\n\nTo thoroughly test and validate the architecture we needed to turn to performance testing and define our methodology. The approach was to target our most common endpoints with a representative test data set at RPS loads that were also representative. Then, although we had manually built the prototype architecture, we knew we needed tooling to automatically build environments and handle tasks such as updates. These efforts resulted in the [GitLab Performance Tool](https://about.gitlab.com/blog/how-were-building-up-performance-testing-of-gitlab/) and [GitLab Environment Toolkit](https://about.gitlab.com/blog/why-we-are-building-the-gitlab-environment-toolkit-to-help-deploy-gitlab-at-scale/), which I blogged about previously and which we continue to use to this day (and you can use too!).\n\nWith all the above in place we started the main work of validating the prototype architecture through multiple cycles of testing and iterating. In each cycle, we would performance test the environment, review the results and metrics, and adjust the environment accordingly. Through iteration we were able to identify what failures were real application performance issues and what were environmental, and eventually we had our first architecture. That architecture is now known as the [200 RPS or 10,000-user Reference Architecture](https://docs.gitlab.com/ee/administration/reference_architectures/10k_users.html).\n\n![GitLab Reference Architecture - 200 RPS](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098658/Blog/Content%20Images/Blog/Content%20Images/reference_architecture_aHR0cHM6_1750098658326.png)\n\n## Where Reference Architectures are today\n\nSince publishing our first validated Reference Architecture, the work has never stopped! We like to describe the architectures as living documentation, as they're constantly being improved and expanded with additions such as:\n\n- various Reference Architecture sizes based on common deployments\n- non-highly available sizes for smaller environments\n- full step-by-step documentation in collaboration with our colleagues in Technical Writing and Support\n- expanded guidance and new naming scheme to help with right sizing, scaling, and how to deal with outliers such as monorepos\n- cloud native hybrid variants where select components are run in Kubernetes\n- recommendations and guidance for cloud provider services\n- and more! Check out the [update history](https://docs.gitlab.com/ee/administration/reference_architectures/#update-history) section in the Reference Architecture documentation!\n\nAll this is driven by our [comprehensive testing program](https://docs.gitlab.com/ee/administration/reference_architectures/#validation-and-test-results) that we built alongside the Reference Architectures to continuously test that they remain fit for purpose against the latest GitLab code _every single week_ and to catch any unexpected performance issues early.\n\nAnd we're thrilled to see these efforts have helped numerous customers to date as well as our own engineering teams deliver new, exciting services. In fact, our engineering teams used the Reference Architectures to develop [GitLab Dedicated](https://about.gitlab.com/dedicated/). Five years on, our commitment is stronger than ever. The work very much continues in the same way it started to ensure you have the best-in-class guidance for your DevSecOps journey.\n\n> Learn more about [GitLab Reference Architectures](https://docs.gitlab.com/ee/administration/reference_architectures/).\n",[825,9,1039,1038,974],{"slug":2525,"featured":91,"template":698},"how-we-designed-the-gitlab-reference-architectures","content:en-us:blog:how-we-designed-the-gitlab-reference-architectures.yml","How We Designed The Gitlab Reference Architectures","en-us/blog/how-we-designed-the-gitlab-reference-architectures.yml","en-us/blog/how-we-designed-the-gitlab-reference-architectures",{"_path":2531,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2532,"content":2537,"config":2542,"_id":2544,"_type":14,"title":2545,"_source":16,"_file":2546,"_stem":2547,"_extension":19},"/en-us/blog/improve-ai-security-in-gitlab-with-composite-identities",{"title":2533,"description":2534,"ogTitle":2533,"ogDescription":2534,"noIndex":6,"ogImage":773,"ogUrl":2535,"ogSiteName":686,"ogType":687,"canonicalUrls":2535,"schema":2536},"Improve AI security in GitLab with composite identities","Learn how to implement AI features responsibly by applying authentication best practices with service accounts for AI agents in GitLab.","https://about.gitlab.com/blog/improve-ai-security-in-gitlab-with-composite-identities","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Improve AI security in GitLab with composite identities\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Grzegorz Bizon\"}],\n        \"datePublished\": \"2025-01-29\",\n      }",{"title":2533,"description":2534,"authors":2538,"heroImage":773,"date":928,"body":2540,"category":694,"tags":2541},[2539],"Grzegorz Bizon","Artificial intelligence (AI) is quickly becoming the backbone of modern software development, fueling developer efficiency and accelerating innovation. With the emergence of AI agents implementing code based on instructions from humans, we are learning that implementing AI-based features has its own unique set of security challenges. **How do we protect access to the resources AI needs, protect confidentiality, and avoid privilege escalation**? Few organizations are ready to answer these questions today. At GitLab, we are. We are introducing a new paradigm for identity management: composite identities.\n\nWhen AI agents are integrated into your DevSecOps workflows, previously simple questions become difficult to answer: Who authored this code? Who is the author of this merge request? Who created this Git commit? We found we had to start asking new questions: Who instructed an AI agent to generate this code? What context did AI need to build this feature? What were the resources AI had to access and read to generate the answer?\n\nTo answer these questions, we need to understand some fundamental aspects of AI’s identity:\n\n* Does an AI agent have its own distinct identity?\n* What is the representation of this identity?\n* How do we make it all secure?\n\n### Authentication and AI identity management \n\nWe are at the beginning of a paradigm shift in identity management in the software delivery lifecycle. Before the AI era, identity management was simpler. We had human user-based identities and machine-type identities using separate accounts.\n\nWith the emergence of AI and agentic workflows, the distinction between these two core types of identities has blurred. AI agents are supposed to work in an autonomous way, so it makes sense to think about them as machine-type accounts. On the other hand, AI agents are usually being instructed by human users, and require access to resources the human users have access to in order to complete their tasks. This introduces significant security risks — for example, the AI may provide human users with information they should not have access to. How do we avoid privilege escalation, provide auditability, and protect confidentiality in a world with AI agents?\n\n### The solution: Composite identities\n\nA composite identity is our new identity [principal](https://cloud.google.com/iam/docs/overview#concepts_related_identity), representing an AI agent’s identity that is linked with the identity of a human user who requests actions from the agent. **This enhances our ability to protect resources stored in GitLab**. Whenever an AI agent with a composite identity attempts to access a resource, we will not only authenticate the agent itself, but also link its principal with a human user who is instructing the agent, and will try to authorize both principals before granting access to a resource. Both principals need access; otherwise, the access will be denied. If an AI agent by itself can access a project, but a human user who instructed the agent to do so cannot, GitLab will deny the access.\n\nThe inverse is true as well — if a human user can access a confidential issue, but an AI agent can’t, then its service account will not be able to read the issue. We authorize access to every API request and for each resource an agent attempts to access this way. Composite identity without a request-scoped link to a human account will not be authorized to access any resource. For fully autonomous workloads we are also considering adding support for linking composite identities with other principals.\n\n#### Composite identity and service accounts\n\nWe redesigned our authorization framework to support composite identities, allowing multiple principals to be evaluated simultaneously when determining access rights to a resource. We enhanced our security infrastructure by implementing scoped identities across our entire system — from API requests to CI jobs and backend workers. These identities are linked to an AI agent's composite identity account also through OAuth tokens and CI job tokens. This project yielded unexpected security benefits, particularly in GitLab CI, where we upgraded job tokens to signed JSON web tokens (JWTs). Additionally, we contributed code to several open source libraries to add support for scoped identities.\n\n### Composite identity with GitLab Duo with Amazon Q\n\nIn the GitLab 17.8 release, we made composite identity for service accounts support available for customers through our GitLab Duo with Amazon Q integration. Amazon Q Developer agent will have composite identity enforced, which will protect your confidential GitLab resources from unauthorized access.\n\n### What’s next?\n\nTo learn more, check out our [composite identity docs](https://docs.gitlab.com/ee/development/ai_features/composite_identity.html).",[717,9,694],{"slug":2543,"featured":6,"template":698},"improve-ai-security-in-gitlab-with-composite-identities","content:en-us:blog:improve-ai-security-in-gitlab-with-composite-identities.yml","Improve Ai Security In Gitlab With Composite Identities","en-us/blog/improve-ai-security-in-gitlab-with-composite-identities.yml","en-us/blog/improve-ai-security-in-gitlab-with-composite-identities",{"_path":2549,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2550,"content":2556,"config":2561,"_id":2563,"_type":14,"title":2564,"_source":16,"_file":2565,"_stem":2566,"_extension":19},"/en-us/blog/improve-security-auditing-with-gitlab-operational-container-scanning",{"title":2551,"description":2552,"ogTitle":2551,"ogDescription":2552,"noIndex":6,"ogImage":2553,"ogUrl":2554,"ogSiteName":686,"ogType":687,"canonicalUrls":2554,"schema":2555},"Improve security auditing with GitLab Operational Container Scanning","Learn how to conduct container vulnerability scans post-deployment to raise awareness of existing threats and to track resolution of vulnerabilities.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664654/Blog/Hero%20Images/AdobeStock_1172300481.jpg","https://about.gitlab.com/blog/improve-security-auditing-with-gitlab-operational-container-scanning","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Improve security auditing with GitLab Operational Container Scanning\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Daniel Helfand\"}],\n        \"datePublished\": \"2025-01-29\",\n      }",{"title":2551,"description":2552,"authors":2557,"heroImage":2553,"date":928,"body":2559,"category":694,"tags":2560},[2558],"Daniel Helfand","Conducting security scans is a regular part of any software development\nprocess. Whether scanning source code (e.g., Java, Python, or other\nlanguages), configuration files (e.g., YAML files), or [container\nimages](https://cloudnativenow.com/kubecon-cnc-na-2024/unlocking-the-full-potential-of-container-vulnerability-scans/),\nthese scanning tools help development teams be proactive about understanding\nand addressing security threats. \n\n\nTraditionally, developers run these [security scans as part of CI/CD\npipelines](https://docs.gitlab.com/ee/user/application_security/container_scanning/).\nBy including these scans in CI/CD, every change to a project will be\nreviewed to see if any vulnerabilities are introduced. Understanding\nsecurity concerns during development helps to assure that changes are\naddressed before they are deployed to a live environment, but there are many\nadditional benefits to conducting container vulnerability scans post\ndeployment as well.\n\n\n[GitLab's Operational Container\nScanning](https://docs.gitlab.com/ee/user/clusters/agent/vulnerabilities.html)\nfeature allows DevSecOps practitioners to run container vulnerability scans\nagainst containers running in a Kubernetes environment. The benefits of\nconducting a vulnerability scan on deployed containers include regularly\nscanning the images for new vulnerabilities that are discovered, tracking\nwhich environments certain vulnerabilities are deployed to, and also\ntracking the progress of resolving these vulnerabilities. \n\n\nThe scans can be configured to run on a regular cadence and on containers in\nspecific namespaces on a Kubernetes cluster. The results of these scans are\nthen sent back to GitLab projects to be viewed via the GitLab UI. To show\nexactly how the feature works, the next steps in this article will\ndemonstrate how to apply the Operational Container Scanning feature using a\nGitLab project, sample application, and a Kubernetes cluster. \n\n\n## Prerequisites\n\n\nTo get started, you will need the following:   \n\n* [GitLab Ultimate account](https://about.gitlab.com/free-trial/)   \n\n* Kubernetes cluster that meets [GitLab’s Kubernetes version\nrequirements](https://docs.gitlab.com/ee/user/clusters/agent/#supported-kubernetes-versions-for-gitlab-features)  \n\n* [kubectl CLI](https://kubernetes.io/docs/tasks/tools/#kubectl)\n\n* [helm CLI](https://helm.sh/docs/intro/install/)\n\n\nAdditionally, the walkthrough below will use a [GitLab\nproject](https://gitlab.com/gitlab-da/tutorials/cloud-native/operational-container-scanning-tutorial)\nthat can be forked into a [GitLab\ngroup](https://docs.gitlab.com/ee/user/group/) where you have appropriate\npermissions to carry out the steps that follow. \n\n\n## Deploy a sample application\n\n\nThe first action we will carry out is to deploy a sample application to the\nKubernetes cluster you will use in this tutorial. Before running the\n`kubectl` command to deploy a sample application, take a moment to make sure\nyour `KUBECONFIG` is set to the cluster you would like to use. Once you are\nset up to use your cluster, run the following command:\n\n\n```bash  \n\n$ kubectl apply -f\n\nhttps://gitlab.com/gitlab-da/tutorials/cloud-native/go-web-server/-/raw/main/manifests/go-web-server-manifests.yaml\n\n\nnamespace/go-web-server-dev created  \n\ndeployment.apps/go-web-server created  \n\nservice/go-web-server created  \n\n```\n\n\nWait for all the pods to be running in the `go-web-server-dev` namespace by\nrunning the command below:\n\n\n```bash  \n\n$ kubectl get pods -n go-web-server-dev -w  \n\n```\n\n\nYou should see output similar to what is shown below:\n\n\n```  \n\nNAME                            READY   STATUS    RESTARTS   AGE  \n\ngo-web-server-f6b8767dc-57269   1/1     Running   0          18m  \n\ngo-web-server-f6b8767dc-fkct2   1/1     Running   0          18m  \n\ngo-web-server-f6b8767dc-j4qwg   1/1     Running   0          18m  \n\n```\n\n\nOnce everything is running, you can set up your forked GitLab project to\nconnect to your Kubernetes cluster and configure the Operational Container\nScanning properties. \n\n\n## Connect Kubernetes cluster\n\n\nIn this section, you will learn how to connect a Kubernetes cluster to your\nGitLab project via the [GitLab Agent for\nKubernetes](https://docs.gitlab.com/ee/user/clusters/agent/). By configuring\nand installing the agent on your Kubernetes cluster, you will be able to\nalso configure Operational Container Scanning. \n\n\n### Change the id property for GitLab’s Kubernetes agent\n\n\nIn the forked GitLab project you are using, change the [`id` property in the\nconfig.yaml\nfile](https://gitlab.com/gitlab-da/tutorials/cloud-native/operational-container-scanning-tutorial/-/blob/main/.gitlab/agents/k8s-agent/config.yaml?ref\\_type=heads\\#L5)\nto match the group where you have forked the project. By doing this, you\nwill configure the GitLab Agent for Kubernetes to pass information about\nyour cluster back to your GitLab project. Make sure to commit and push this\nchange back to the main branch of the forked project.\n\n\n### Navigate to Kubernetes clusters page of the project\n\n\nIn the GitLab UI, select the **Operate > Kubernetes clusters** tab of the\nforked project. Click the **Connect a cluster (agent)** button. Add the name\nof the agent to the input box under `Option 2: Create and register an agent\nwith the UI` and then click **Create and register**. In this case, the name\nof the agent is `k8s-agent` since the folder under agents with the\n`config.yaml` file is named `k8s-agent`. Note that this folder can have any\nname that follows [Kubernetes naming\nrestrictions](https://docs.gitlab.com/ee/user/clusters/agent/install/#create-an-agent-configuration-file)\nand that `k8s-agent` is just being used for simplicity.\n\n\n### Install the GitLab Kubernetes agent\n\n\nAfter registering the agent, you will be asked to run a helm command shown\nin the GitLab UI from your command line against your Kubernetes cluster.\nBefore running the command, make sure your `KUBECONFIG` is still connected\nto the same cluster where you deployed the sample application. \n\n\nAfter running the helm command successfully, wait for all pods to be running\nin the `gitlab-agent-k8s-agent` namespace on your cluster. You can wait for\neverything to be running using the following command: \n\n\n```bash  \n\n$ kubectl get pods -n gitlab-agent-k8s-agent -w  \n\n``` \n\n\nYou should see similar output to what is shown below:\n\n\n```  \n\nNAME                                         READY   STATUS    RESTARTS  \nAGE  \n\nk8s-agent-gitlab-agent-v2-6bb676b6bf-v4qml   1/1     Running   0         \n10m  \n\nk8s-agent-gitlab-agent-v2-6bb676b6bf-xt7xh   1/1     Running   0         \n10m  \n\n```\n\n\nOnce the pods are running, your GitLab project should be connected to your\nKubernetes cluster and ready to use the Operational Container Scanning\nfeature. Before proceeding, continue running the `kubectl get pods -n\ngitlab-agent-k8s-agent -w` command to help explain concepts in the next\nsection.\n\n\n## Operational Container Scanning\n\n\nIn addition to the pods for the GitLab agent running in the\n`gitlab-agent-k8s-agent` namespace, there should eventually be another pod\nnamed `trivy-scan-go-web-server-dev`. This pod will start and run on a\nregular cadence and conduct a container vulnerability scan using a tool\nnamed [trivy](https://trivy.dev/latest/) against the `go-web-server-dev`\nnamespace where the sample application deployed earlier is running. \n\n\nThe Operational Container Scanning properties are defined in the\n[`config.yaml`\nfile](https://gitlab.com/gitlab-da/tutorials/cloud-native/operational-container-scanning-tutorial/-/blob/main/.gitlab/agents/k8s-agent/config.yaml?ref_type=heads#L6-L10)\nused to set up the GitLab agent for Kubernetes on your cluster. \n\n\nThe two main properties to define are `cadence`, which specifies how\nfrequently to run the container vulnerability scan, and also the\n`namespaces` property nested under `vulnerability_report`, which defines one\nor more namespaces to conduct the scan on. You can see how this looks in\n`config.yaml` below:\n\n\n```yaml  \n\ncontainer_scanning:  \n  cadence: '*/5 * * * *'  \n  vulnerability_report:  \n    namespaces:  \n      - go-web-server-dev  \n```\n\n\nThe cadence follows a cron format. In this case, `*/5 * * * *` means the\nscan will be run every five minutes, but this can be changed to any amount\nof time (e.g., every 24 hours).  \n\n\nThe vulnerabilities revealed by the scan for containers running in the\n`go-web-server-dev` namespace are sent back to your GitLab project. To see\nthe results, go to the GitLab UI and select your forked project. Select the\n**Secure > Vulnerability report** option for the project and then select the\n**Operational vulnerabilities** tab to view scan results. \n\n\nThe scan results will include information on the severity of the common\nvulnerabilities and exposures (CVEs), along with the name of the image. By\nusing the tag of the image to include the version of the deployed software\nalong with what environment it is deployed to, you can begin to audit what\nknown vulnerabilities exist in your Kubernetes environments and keep track\nof how they are being addressed by engineering teams.\n\n\nWatch this demo for more information:\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/2FVQec2J-Ew?si=T6kwPMnPAGwKlkfP\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n## Share your feedback\n\n\nAdding GitLab’s Operational Container Scanning to your Kubernetes\nenvironments can help development, security, and infrastructure teams have a\nconsistent picture of container security in Kubernetes environments across\nan organization. In addition to GitLab’s CI container scanning capabilities\nand the ability to [scan containers pushed to GitLab’s container\nregistry](https://www.youtube.com/watch?v=Zuk7Axs-CRw), GitLab has solutions\nat every phase of the software development lifecycle to address container\nsecurity concerns.\n\n\nYou can share your feedback on Operational Container Scanning in this [forum\npost](https://forum.gitlab.com/t/operational-container-scanning-feedback/119479),\nwhich we will share with our product and engineering teams supporting this\nfeature. You can get started with Operational Container Scanning by reading\nthe [documentation on the\nfeature](https://docs.gitlab.com/ee/user/clusters/agent/vulnerabilities.html)\nand [starting a free trial of GitLab\nUltimate](https://about.gitlab.com/free-trial/).\n",[719,9,827,694,848],{"slug":2562,"featured":6,"template":698},"improve-security-auditing-with-gitlab-operational-container-scanning","content:en-us:blog:improve-security-auditing-with-gitlab-operational-container-scanning.yml","Improve Security Auditing With Gitlab Operational Container Scanning","en-us/blog/improve-security-auditing-with-gitlab-operational-container-scanning.yml","en-us/blog/improve-security-auditing-with-gitlab-operational-container-scanning",{"_path":2568,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2569,"content":2575,"config":2581,"_id":2583,"_type":14,"title":2584,"_source":16,"_file":2585,"_stem":2586,"_extension":19},"/en-us/blog/inside-dora-performers-score-in-gitlab-value-streams-dashboard",{"title":2570,"description":2571,"ogTitle":2570,"ogDescription":2571,"noIndex":6,"ogImage":2572,"ogUrl":2573,"ogSiteName":686,"ogType":687,"canonicalUrls":2573,"schema":2574},"Inside DORA Performers score in GitLab Value Streams Dashboard ","Learn how four key metrics drive DevOps maturity, helping teams optimize workflows and achieve DevOps excellence.\n","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098908/Blog/Hero%20Images/Blog/Hero%20Images/AdobeStock_644947854_248JIrEOCaGJdfJdiSjYde_1750098907747.jpg","https://about.gitlab.com/blog/inside-dora-performers-score-in-gitlab-value-streams-dashboard","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Inside DORA Performers score in GitLab Value Streams Dashboard \",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Haim Snir\"}],\n        \"datePublished\": \"2024-01-18\",\n      }",{"title":2570,"description":2571,"authors":2576,"heroImage":2572,"date":2578,"body":2579,"category":10,"tags":2580},[2577],"Haim Snir","2024-01-18","The DevOps Research and Assessment ([DORA](https://docs.gitlab.com/ee/user/analytics/dora_metrics.html)) metrics are industry-standard measurements to help better understand the capabilities that drive software delivery and operations performance. GitLab recently added a DORA Performers score panel to the Value Streams Dashboard in the GitLab DevSecOps Platform to visualize the status of the organization's DevOps performance across different projects.\n\nThis new visualization displays a breakdown of the DORA performance levels, designating a score level for each project under a group. Executives can use this visualization to easily identify the highs and lows in DORA scores and understand their organization's DevOps health top to bottom.\n\n> [Try the Value Streams Dashboard today.](https://about.gitlab.com/blog/getting-started-with-value-streams-dashboard/)\n\n## What are DORA metrics?\n\nDuring the past nine years, the DORA team gathered insights from over 36,000 professionals around the globe on how to measure the performance of a software development team. They identified four metrics as key indicators to measure software teams' development effectiveness and efficiency:\n\n- [Deployment frequency](https://docs.gitlab.com/ee/user/analytics/dora_metrics.html#deployment-frequency) and [Lead time for changes](https://docs.gitlab.com/ee/user/analytics/dora_metrics.html#lead-time-for-changes) measure team velocity.\n- [Change failure rate](https://docs.gitlab.com/ee/user/analytics/dora_metrics.html#change-failure-rate) and [Time to restore service](https://docs.gitlab.com/ee/user/analytics/dora_metrics.html#time-to-restore-service) measure stability.\n\nBy analyzing these metrics, teams are able to find areas for improvement, optimize their workflows, and ultimately drive positive business results.\n\nDORA uses these metrics to identify high-performing, medium-performing, and low-performing teams.  These performance levels provide a framework for organizations to assess their DevOps maturity and effectiveness.\n\n![DORA performers](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098929/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098929143.png)\n\nHigh performance indicates that the team is operating at excellent speed and stability in their software delivery, reaching the peak of DevOps maturity.\n\nMedium and low performance levels suggest opportunities for improvement in different aspects of the software development and delivery process.\n\nLet's take a closer look at the DORA definition for each performance level.\n\n![Chart of performance metrics](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098929/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098929144.png)\n\u003Csup>\u003Csub>_Source: [DORA Accelerate State of DevOps report](https://cloud.google.com/blog/products/devops-sre/dora-2022-accelerate-state-of-devops-report-now-out)_\u003C/sub>\u003C/sup>\u003Cp>\u003C/p>\n\n## GitLab definitions for the DORA score performance levels\n\nDORA metrics are available out of the box in the GitLab DevSecOps platform. To enable the score calculation to operate \"out of the box\" with GitLab, we adjust the scoring rules so they work with the platform's unified data model. Read more in the [score definition documentation](https://docs.gitlab.com/ee/user/analytics/value_streams_dashboard.html#dora-performers-score-panel).\n\nThe goal is for organizations to strive for high performance in these metrics, as a high score often correlates with better business outcomes, such as increased efficiency, faster time-to-market, and higher software quality.\n\n## DORA metrics in GitLab\n\nIn addition to the Value Streams dashboard, the DORA metrics are available also on the [CI/CD analytics charts](https://docs.gitlab.com/ee/user/analytics/ci_cd_analytics.html), which show the history of DORA metrics over time, and on [Insights reports](https://docs.gitlab.com/ee/user/project/insights/index.html#dora-query-parameters) where you can create custom charts.\n\nWatch our DORA overview video:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n \u003Ciframe src=\"https://www.youtube.com/embed/jYQSH4EY6_U?si=sE9rf_X58BGD2uK9\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Get started today\nYou can get started with the Value Streams Dashboard by [following the instructions](https://about.gitlab.com/blog/getting-started-with-value-streams-dashboard/) in this documentation. Then, to help us improve the value of the Value Streams Dashboard, please share feedback about your experience in this [brief survey](https://gitlab.fra1.qualtrics.com/jfe/form/SV_50guMGNU2HhLeT4).\n",[1299,9,496,848,1039],{"slug":2582,"featured":6,"template":698},"inside-dora-performers-score-in-gitlab-value-streams-dashboard","content:en-us:blog:inside-dora-performers-score-in-gitlab-value-streams-dashboard.yml","Inside Dora Performers Score In Gitlab Value Streams Dashboard","en-us/blog/inside-dora-performers-score-in-gitlab-value-streams-dashboard.yml","en-us/blog/inside-dora-performers-score-in-gitlab-value-streams-dashboard",{"_path":2588,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2589,"content":2595,"config":2600,"_id":2602,"_type":14,"title":2603,"_source":16,"_file":2604,"_stem":2605,"_extension":19},"/en-us/blog/interactive-take-a-guided-tour-of-the-devsecops-workflow",{"title":2590,"description":2591,"ogTitle":2590,"ogDescription":2591,"noIndex":6,"ogImage":2592,"ogUrl":2593,"ogSiteName":686,"ogType":687,"canonicalUrls":2593,"schema":2594},"Interactive: Take a guided tour of the DevSecOps workflow","Explore GitLab's recommended best practices for DevSecOps with a detailed visual depiction of the main steps in the development lifecycle.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749668969/Blog/Hero%20Images/blog-image-template-1800x945__1800_x_945_px_.png","https://about.gitlab.com/blog/interactive-take-a-guided-tour-of-the-devsecops-workflow","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Interactive: Take a guided tour of the DevSecOps workflow\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"}],\n        \"datePublished\": \"2024-04-16\",\n      }",{"title":2590,"description":2591,"authors":2596,"heroImage":2592,"date":2597,"body":2598,"category":10,"tags":2599},[1612],"2024-04-16","When engaging in discussions with industry professionals and stakeholders, they quickly grasp the core principles of DevSecOps, which emphasize speed, security, and quality. However, there's often a curiosity about the specific strategies required to achieve optimal speed without compromising security and quality. We created this interactive infographic to showcase GitLab's best practices for [DevSecOps](https://about.gitlab.com/topics/devsecops/) through a detailed visual depiction of the main steps in the development lifecycle.\n\nWalk through every step of the DevSecOps process, including creation of [issues](https://docs.gitlab.com/ee/user/project/issues/), development and pushing of code, [security testing](https://about.gitlab.com/stages-devops-lifecycle/secure/), and deployment to production. Each step features a deep dive with additional resources such as demos, blog posts, and documentation.\n\n## Get started with the interactive tour\n\nClick on the image below to access the guided tour, and use the navigation buttons or keyword arrows to easily make your way through the flow.\n\n[![GitLab workflow description](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749676928/Blog/Content%20Images/infographic.png)](https://tech-marketing.gitlab.io/static-demos/gitlab-infographic.html)\n\n\u003Cp>\u003C/p>\n\n> > Learn how [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our suite of AI-powered features, further enhances the DevSecOps workflow.\n",[9,1016,109],{"slug":2601,"featured":91,"template":698},"interactive-take-a-guided-tour-of-the-devsecops-workflow","content:en-us:blog:interactive-take-a-guided-tour-of-the-devsecops-workflow.yml","Interactive Take A Guided Tour Of The Devsecops Workflow","en-us/blog/interactive-take-a-guided-tour-of-the-devsecops-workflow.yml","en-us/blog/interactive-take-a-guided-tour-of-the-devsecops-workflow",{"_path":2607,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2608,"content":2614,"config":2620,"_id":2622,"_type":14,"title":2623,"_source":16,"_file":2624,"_stem":2625,"_extension":19},"/en-us/blog/introducing-gitlabs-open-source-security-center",{"title":2609,"description":2610,"ogTitle":2609,"ogDescription":2610,"noIndex":6,"ogImage":2611,"ogUrl":2612,"ogSiteName":686,"ogType":687,"canonicalUrls":2612,"schema":2613},"Introducing GitLab’s Open Source Security Center","Our open source repository of projects designed to enhance security operations and risk management will help developers adapt faster, respond smarter, and defend better — together.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749661895/Blog/Hero%20Images/blog-image-template-1800x945__7_.png","https://about.gitlab.com/blog/introducing-gitlabs-open-source-security-center","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Introducing GitLab’s Open Source Security Center\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Salman Ladha\"},{\"@type\":\"Person\",\"name\":\"Joseph Longo\"}],\n        \"datePublished\": \"2025-03-04\",\n      }",{"title":2609,"description":2610,"authors":2615,"heroImage":2611,"date":2617,"body":2618,"category":694,"tags":2619},[1710,2616],"Joseph Longo","2025-03-04","Today, we’re excited to announce the launch of [GitLab’s Open Source Security Center](https://about.gitlab.com/security/open-source-resources/) — a central repository of security-focused projects developed by GitLab’s internal security team. These tools are designed to help developers, security practitioners, and organizations build safer, more secure software, and more resilient security programs.\n\nSecuring systems is an ongoing challenge for businesses as threat actors continually adapt to new technologies and find creative ways to exploit organizations. Not only are they evolving their tactics, techniques and procedures, but they’re also [collaborating through criminal networks](https://insights.blackhatmea.com/do-cybercriminals-collaborate-and-build-community/), sharing strategies, stolen data, and malicious tools to launch coordinated attacks at scale. \n\nAs these threats grow in complexity, community-driven collaboration is one of our most powerful defenses. It’s a notion we’ve long understood in security — that *defending against adversaries is a shared responsibility*. By working together as a community, we can accelerate our collective intelligence and stay ahead of adversaries.\n\nIn open-sourcing our security solutions, we aim to empower teams to adapt faster, respond smarter, and defend better — together.\n\n[![Open Source Security Center page image](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674572/Blog/Content%20Images/Screenshot_2025-03-04_at_08.10.05.png)](https://about.gitlab.com/security/open-source-resources/)\n\n## Why open source security? \n\nAt GitLab, open source isn’t just part of our technology — it’s part of our [founding story](https://about.gitlab.com/company/).\n\nSince day one, we’ve championed the open source philosophy, believing that transparency, collaboration, and community-driven development are keys to building better software. Over the years, GitLab has fostered an open source community with more than [4,000 contributors](https://about.gitlab.com/community/contribute/) and has provided a comprehensive DevSecOps platform through its open source [Community Edition](https://about.gitlab.com/install/ce-or-ee/).\n\nWe’ve also been inspired by industry leaders like [Crowdstrike](https://opensource.crowdstrike.com/) and [Palo Alto Networks](https://www.paloaltonetworks.ca/prisma/cloud/open-source-projects), who have shown that open-sourcing security tools not only improves innovation but also strengthens the entire security ecosystem. Following in their footsteps, GitLab is committed to supporting the community by sharing tools, templates, and frameworks developed by our security teams.\n\n## Explore our featured open source security projects\n\nWe’re launching the Open Source Security Center with a range of projects designed to enhance security operations and risk management. Here are some of the featured projects:\n\n* **[StORM templates](https://gitlab.com/gitlab-security-oss/risk-mgmt/storm-templates/):** Streamline your security risk program with templates that standardize risk tracking and reporting.\n\n* **[GUARD Framework](https://about.gitlab.com/blog/unveiling-the-guard-framework-to-automate-security-detections-at-gitlab/):** Automate response and detection with a detections-as-code approach that simplifies detection creation, maintenance, and alert routing.  \n\n* **[GitLab CIS Benchmark Scanner](https://about.gitlab.com/blog/new-cis-gitlab-benchmark-scanner-boosts-security-and-compliance/):** Improve your project’s security posture by auditing against the Center for Internet Security GitLab Benchmark.\n\nWhether you’re a security engineer, researcher, or developer, your expertise and contributions are invaluable. Join us in strengthening the security ecosystem and collaborating with a community dedicated to making software safer for everyone.\n\n> [Explore GitLab’s Open Source Security Center](https://about.gitlab.com/security/open-source-resources/) and contribute to the next chapter of open source security. \n\n## Learn more\n\n- [New CIS GitLab Benchmark scanner boosts security and compliance](https://about.gitlab.com/blog/new-cis-gitlab-benchmark-scanner-boosts-security-and-compliance/)\n- [GitLab introduces new CIS Benchmark for improved security](https://about.gitlab.com/blog/gitlab-introduces-new-cis-benchmark-for-improved-security/)\n- [Unveiling the GUARD framework to automate security detections at GitLab](https://about.gitlab.com/blog/unveiling-the-guard-framework-to-automate-security-detections-at-gitlab/)\n- [Automating cybersecurity threat detections with GitLab CI/CD](https://about.gitlab.com/blog/automating-cybersecurity-threat-detections-with-gitlab-ci-cd/)",[694,994,803,9,719],{"slug":2621,"featured":91,"template":698},"introducing-gitlabs-open-source-security-center","content:en-us:blog:introducing-gitlabs-open-source-security-center.yml","Introducing Gitlabs Open Source Security Center","en-us/blog/introducing-gitlabs-open-source-security-center.yml","en-us/blog/introducing-gitlabs-open-source-security-center",{"_path":2627,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2628,"content":2634,"config":2640,"_id":2642,"_type":14,"title":2643,"_source":16,"_file":2644,"_stem":2645,"_extension":19},"/en-us/blog/introducing-the-source-insights-for-the-future-of-software-development",{"title":2629,"description":2630,"ogTitle":2629,"ogDescription":2630,"noIndex":6,"ogImage":2631,"ogUrl":2632,"ogSiteName":686,"ogType":687,"canonicalUrls":2632,"schema":2633},"Introducing The Source: Insights for the future of software development","Explore our new publication for transformative software development strategies and expert advice on emerging technologies.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674616/Blog/Hero%20Images/blog-image-template-1800x945__1_.png","https://about.gitlab.com/blog/introducing-the-source-insights-for-the-future-of-software-development","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Introducing The Source: Insights for the future of software development\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Chandler Gibbons\"}],\n        \"datePublished\": \"2024-10-29\",\n      }",{"title":2629,"description":2630,"authors":2635,"heroImage":2631,"date":2637,"body":2638,"category":994,"tags":2639},[2636],"Chandler Gibbons","2024-10-29","Modern software development is transforming the way organizations create, deliver, and scale business value. Teams must be able to build solutions quickly and efficiently while navigating rising security threats, emerging technologies, and increasingly complex compliance demands.\n\nToday, GitLab is launching [The Source](https://about.gitlab.com/the-source/), a new publication that covers the evolution of software development as an engine for business success. We offer regular insights into the future of software development, supported by original research and analysis from our subject matter experts and thought leaders.\n\nOn The Source, you will find answers to questions such as:\n* How can leaders measure the ROI of AI across the software development lifecycle?\n* What’s the best way to ensure security and compliance across the entire software supply chain?\n* What types of efficiencies will teams see from platform and toolchain consolidation?\n\nHere’s a sample of what's on The Source today:\n\n**4 steps for measuring the impact of AI**\n\n\"Evaluating the productivity of AI-enhanced coding requires a more nuanced approach than traditional metrics such as lines of code, code commits, or task completion. It necessitates shifting the focus to real-world business outcomes that balance development speed, software quality, and security.\"\n- [Learn the 4 steps from AI expert Taylor McCaslin.](https://about.gitlab.com/the-source/ai/4-steps-for-measuring-the-impact-of-ai/)\n\n**Addressing the root cause of common security frustrations**\n\n\"DevSecOps promises better integration between engineering and security, but it’s clear that frustrations and misalignment persist. That’s because these challenges are symptoms of a larger problem with how organizations view security, as well as how teams work together and how they allocate time to security.\"\n- [Solve this disconnect with expert advice from GitLab CISO Josh Lemos.](https://about.gitlab.com/the-source/security/security-its-more-than-culture-addressing-the-root-cause-of-common-security/)\n\n**Driving business results with platform engineering**\n\n\"Platform engineering aims to normalize and standardize developer workflows by providing developers with optimized 'golden paths' for most of their workloads and flexibility to define exceptions for the rest.\"\n- [Discover GitLab Field CTO Brian Wald's best practices for platform engineering success.](https://about.gitlab.com/the-source/platform/driving-business-results-with-platform-engineering/)\n\n## Make The Source your decision-making partner\n\nVisit [The Source](https://about.gitlab.com/the-source/) today to explore the latest insights, get answers to your leadership questions, and learn something new to share with your teams. You can also subscribe to our newsletter for regular updates directly to your inbox. Join our community of forward-thinking technology leaders and help shape the future of software development.",[717,694,994,9],{"slug":2641,"featured":91,"template":698},"introducing-the-source-insights-for-the-future-of-software-development","content:en-us:blog:introducing-the-source-insights-for-the-future-of-software-development.yml","Introducing The Source Insights For The Future Of Software Development","en-us/blog/introducing-the-source-insights-for-the-future-of-software-development.yml","en-us/blog/introducing-the-source-insights-for-the-future-of-software-development",{"_path":2647,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2648,"content":2653,"config":2658,"_id":2660,"_type":14,"title":2661,"_source":16,"_file":2662,"_stem":2663,"_extension":19},"/en-us/blog/jenkins-gitlab-ultimate-guide-to-modernizing-cicd-environment",{"title":2649,"description":2650,"ogTitle":2649,"ogDescription":2650,"noIndex":6,"ogImage":965,"ogUrl":2651,"ogSiteName":686,"ogType":687,"canonicalUrls":2651,"schema":2652},"Jenkins to GitLab: The ultimate guide to modernizing your CI/CD environment","Learn how to migrate from Jenkins to the integrated CI/CD of the GitLab DevSecOps Platform to deliver high-quality software rapidly.","https://about.gitlab.com/blog/jenkins-gitlab-ultimate-guide-to-modernizing-cicd-environment","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Jenkins to GitLab: The ultimate guide to modernizing your CI/CD environment\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"}],\n        \"datePublished\": \"2023-11-01\",\n      }",{"title":2649,"description":2650,"authors":2654,"heroImage":965,"date":2655,"body":2656,"category":10,"tags":2657},[1612],"2023-11-01","\nIn today's dynamic landscape of software development, certain requirements have become paramount for delivering high-quality software rapidly. These requirements include the need for cloud compatibility, faster development cycles, improved collaboration, containerization, enhanced development experiences, and the integration of AI-driven capabilities for better efficiency and speed. Jenkins, a longstanding and respected continuous integration (CI) tool, has admirably played a role in many teams' software development for years. However, as more teams adopt DevOps/DevSecOps strategies for their software delivery, leveraging the integrated CI that is available in a DevSecOps platform like GitLab can provide benefits that Jenkins does not. \n\nSome organizations find themselves hesitating to migrate, not because they doubt the benefits of a top-tier [CI/CD](https://about.gitlab.com/topics/ci-cd/) solution such as GitLab, but due to the complexities of their existing Jenkins implementations. It's understandable that such a transition can seem daunting. \n\nIn this blog, you'll find several migration strategies to help transition from Jenkins to GitLab and make the process smoother and more manageable.\n\n## Migrating to GitLab\nIt's become evident that for organizations seeking a CI/CD solution that can seamlessly support their evolving demands, GitLab emerges as a powerful game-changer. Let's explore why transitioning to this advanced platform is transformative for Jenkins users.\n\n### Why migrate to GitLab \nBefore we delve into the migration approaches, let's take a moment to understand GitLab CI and what makes it a compelling choice for modern CI/CD needs.\n\n> Try GitLab CI/CD today with [a free trial of Ultimate](https://gitlab.com/-/trials/new).\n\n### GitLab CI overview\nGitLab CI is an integral part of the GitLab [AI-powered](https://about.gitlab.com/gitlab-duo/) DevSecOps Platform, which offers a comprehensive and unified solution for DevSecOps and CI/CD. GitLab's design revolves around streamlining development workflows, fostering collaboration, enhancing security, and ensuring scalability.\n\n### Key features of GitLab CI\nThese are the key features of GitLab CI:\n- **Unified platform:** GitLab CI is more than just a CI/CD tool; it's part of a broader ecosystem that includes source code management, project management, security features, analytics and more. This unified platform streamlines workflows and enhances collaboration among development teams.\n- **Containerization and orchestration:** GitLab CI/CD is designed with containerization in mind, offering native support for Docker and Kubernetes. This enables seamless integration of container technologies into your CI/CD pipelines.\n- **Security by design:** Security is a top priority, and GitLab CI incorporates features such as static code analysis and vulnerability scanning to help teams identify and address security issues early in the development process.\n- **GitOps principles:** GitLab CI aligns with [GitOps principles](https://about.gitlab.com/blog/the-ultimate-guide-to-gitops-with-gitlab/), emphasizing version-controlled, declarative configurations for infrastructure and application deployments. This approach enhances the reliability and repeatability of deployments.\n\nGet familiar with GitLab CI with this tutorial:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/WKR-7clknsA?si=T21Fe10Oa0rQ0SGB\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nWith that understanding of GitLab CI's capabilities, let's explore the migration steps and strategies for Jenkins users looking to leverage the benefits of GitLab CI.\n\n## A recommended step-by-step Jenkins-to-GitLab CI migration\nWhen considering a migration from Jenkins to GitLab CI, we strongly recommend following a well-structured, step-by-step approach to ensure a seamless transition. Here's our recommended process:\n1. **Pipeline assessment:** Start by conducting a comprehensive inventory of all your existing pipelines in Jenkins. This initial step will help you gain a clear understanding of the scope and complexity of the migration.\n2. **Parallel migration:** Begin the migration process by selecting individual pipelines and moving them to GitLab CI one at a time. Continue to maintain the use of Jenkins for your ongoing work during this transition to minimize disruptions.\n3. **Code verification:** We advise beginning with verification checks in CI. Run both the Jenkins and GitLab CI pipelines in parallel. This dual approach allows you to directly compare the two workflows and identify any issues in the new GitLab workflows. During this phase, keep the GitLab workflow as an optional choice while Jenkins remains required.\n4. **Continuous validation:** After running both pipelines in parallel for a full iteration, thoroughly evaluate the outcomes from each pipeline. This evaluation should consider various factors, including status codes, logs, and performance. \n5. **GitLab CI transition:** As you gain confidence in the reliability and effectiveness of GitLab CI through the parallel runs, make the transition to the GitLab CI workflow as the required standard while Jenkins continues to operate in the background.\n6. **Jenkins phaseout:** After a second iteration, when you are confident in the performance and stability of GitLab CI, you can begin to remove the Jenkins job from your code verification pipeline. This successful transition will enable you to retire Jenkins from this particular aspect of your CI/CD process.\n\nThis recommended approach ensures that your migration is a gradual evolution, allowing you to identify and address any issues or discrepancies before fully committing to GitLab CI. Running Jenkins and GitLab CI pipelines in parallel provides valuable insights and ensures the effective streamlining of your CI/CD processes.\n\n## Preparing for migration: Training and communication\nTo ensure a smooth and successful migration from Jenkins to GitLab CI, follow these essential steps:\n- **Stakeholder communication:** Start by announcing your migration plans and timelines to all relevant stakeholders. This includes DevOps teams, developers, and QA engineers. Transparency in communication is crucial to ensure that everyone understands the objectives and expectations of the migration.\n- **Knowledge-level training:** Conduct knowledge-level training sessions for your teams to promote GitLab CI adoption.\nCover topics such as using GitLab CI, understanding the YAML syntax, and how to create a basic pipeline.\nProvide team members with the knowledge and skills necessary to navigate the new GitLab CI environment effectively.\n- **Hands-on learning:** Encourage hands-on learning by pairing up developers.\nCreate opportunities for them to learn from each other's experiences throughout the migration process.\n\nBy following these instructions for training and communication, you'll build a strong foundation for a successful migration, empowering your teams to adapt and thrive in the new environment.\n\n## 3 Jenkins-to-GitLab CI migration strategies\nThere are different strategies to consider. These three strategies offer flexibility, allowing organizations to choose the path that best aligns with their specific needs and resources. Let's explore these strategies in detail to help you make an informed decision about which one suits your organization best.\n\n### Migration Strategy 1: Using GitLab CI for new projects\nThe first migration strategy involves a gradual transition. While you maintain your existing Jenkins infrastructure for ongoing projects, you introduce GitLab CI for new projects. This approach allows you to harness the modern features of GitLab CI without disrupting your current work.\n\n#### Benefits of Migration Strategy 1\nThe benefits of this approach include the following:\n- New projects can leverage GitLab CI's advanced features right from the start. \n- This strategy minimizes the risk of disrupting existing workflows, as your existing Jenkins setup remains intact.\n- Your team can gradually adapt to GitLab CI, building confidence and expertise without the pressure of an immediate full-scale migration.\n\n#### Challenges of Migration Strategy 1\nThe challenges of this approach include the following:\n- Operating two CI/CD platforms simultaneously can introduce complexity, especially in terms of integration and team collaboration.\n- Managing projects on different platforms may require careful coordination to ensure consistency in processes and security practices.\n\nThis strategy offers a smooth and manageable transition by allowing you to harness GitLab CI's strengths for new projects, while your existing Jenkins infrastructure continues to support ongoing work.\n\n### Migration Strategy 2: Migrating only strategic projects\nIn this strategy, you identify specific projects within your organization that stand to benefit the most from the capabilities of GitLab CI. Instead of preparing for a wholesale migration, you start by focusing your efforts on migrating these strategically selected projects first.\n\n#### Benefits of Migration Strategy 2\nThe benefits of this approach include the following:\n- By concentrating on key projects, you can realize significant improvements in those areas where GitLab CI aligns with specific needs.\n- This approach reduces the complexity of migrating everything at once, minimizing the potential for disruptions.\n- You can gradually build confidence with GitLab CI and its benefits before considering further migrations.\n\n#### Challenges of Migration Strategy 2\nThe challenges of this approach include the following:\n- Even though you're not migrating all projects, the chosen projects' migration can still be intricate and require careful planning.\n- Ensuring seamless collaboration between projects on different platforms may require additional attention.\n\nThis strategy allows you to maximize the impact of GitLab CI by focusing on strategic areas, minimizing risk, and gradually gaining experience with the new tool.\n\n### Migration Strategy 3: Migrating everything\nThe third strategy is a comprehensive migration where you commit to moving all your CI/CD processes, projects, and workflows to GitLab CI. This approach aims for uniformity and simplification of CI/CD across all projects. This strategy can benefit from taking an iterative approach. Consider starting with new projects, followed by migrating strategic projects, and then leverage your growing knowledge and experience with GitLab CI to complete the migration of remaining projects. \n\n#### Benefits of Migration Strategy 3\nThe benefits of this approach include the following:\n- Uniform CI/CD processes across all projects can streamline administration and maintenance, reducing complexity.\n- You can take full advantage of GitLab CI's modern capabilities, from Infrastructure as Code to enhanced security features.\n- As your projects grow, GitLab CI is designed to handle increased demands, ensuring long-term scalability.\n\n#### Challenges of Migration Strategy 3\nThe challenges of this approach include the following:\n- A full-scale migration can be intricate, requiring meticulous planning and implementation.\n- The transition may disrupt ongoing projects and require a significant time investment.\n- Investment in training and potential tool migration expenses should be considered.\n\nOpt for this approach if uniformity and consolidation of CI/CD processes are a high priority, and you have the resources to execute a full migration.\n\nThe migration strategy you select should align with your organization's specific needs and circumstances. In all cases, the ultimate goal is to enhance your development process with modern CI/CD tools like GitLab CI, which offers scalability, infrastructure automation, security, and collaboration features that align with today's development needs.\n\n## Technical insights: How the migration works\nMoving your CI/CD workflows from Jenkins to GitLab CI is a transformative journey, and understanding how it works is vital for a successful transition.\n\n### Understanding the configurations: Jenkinsfile vs. .gitlab-ci.yml\nThe heart of your CI/CD pipeline lies in the configurations defined in your Jenkinsfile (for Jenkins) and .gitlab-ci.yml (for GitLab CI). While there are some similarities between these configuration files, there are notable differences as well.\n\n#### Similarities\n- Both files define the stages, jobs, and steps of your CI/CD process.\n- You specify the desired build, test, and deployment steps in both files.\n- Environment variables and settings can be configured in either file.\n\n#### Differences\n- Jenkinsfile uses Groovy for scripting, while .gitlab-ci.yml uses YAML. This change in language affects the way you write and structure your configurations.\n- The process of defining pipelines is more intuitive in .gitlab-ci.yml, with a cleaner, more human-readable syntax.\n- GitLab CI provides a wide range of built-in templates and predefined jobs, simplifying configuration and reducing the need for custom scripting.\n\n### Manually converting the pipeline configuration\nCurrently, migrating your existing Jenkins pipelines to GitLab CI is typically done manually. This means analyzing your Jenkinsfile and re-creating the equivalent configurations in .gitlab-ci.yml. While there are similarities in the concepts and structure, the differences in syntax and the specific capabilities of each platform require careful consideration during the migration.\n\n## Strategic planning for a smooth transition\nMigrating from Jenkins to GitLab CI requires meticulous planning to ensure a seamless transition. It's crucial to assess the disparities between the two systems and evaluate their impact on your workflow, considering aspects like security, cost, time, and capacity.\n\nOnce you've identified these differences and devised your migration strategy, break down the migration into key steps. These include setting up GitLab CI pipelines, securely transferring data from Jenkins to GitLab CI, and integrating GitLab CI into your existing tools and processes. \n\n## Case study: A seamless transition for Lockheed Martin\nLet's look at a real-world case study to illustrate the effectiveness of the \"Migrate Everything\" strategy. [Lockheed Martin](https://about.gitlab.com/customers/lockheed-martin/), the world’s largest defense contractor, had been using Jenkins for several years. As their project portfolio expanded, they realized that their Jenkins implementation with a wide variety of DevOps tools was becoming increasingly complex to manage. They were also eager to adopt modern CI/CD capabilities that Jenkins struggled to provide.\n\nIn collaboration with GitLab, Lockheed Martin decided to undertake a comprehensive migration to GitLab CI. Their goals included achieving consistency in their CI/CD processes, simplifying administration and maintenance, and taking full advantage of The GitLab Platform’s robust features.\n\nThe comprehensive migration strategy proved to be a resounding success for Lockheed Martin. With GitLab CI, they not only streamlined their CI/CD processes but achieved remarkable results. **They managed to run CI pipeline builds a staggering 80 times faster, retired thousands of Jenkins servers, and reduced the time spent on system maintenance by a staggering 90%. This monumental shift resulted in a significant increase in efficiency and productivity for Lockheed Martin.**\n\nThis case study showcases how a comprehensive migration strategy can be effective for organizations looking to leverage GitLab capabilities across all their projects.\n\nFor more in-depth insights into Lockheed Martin's successful transition to GitLab and how it streamlined their software development processes, check out [the detailed case study](https://about.gitlab.com/customers/lockheed-martin/).\n\n## GitLab documentation and support\nFor those embarking on this migration journey, GitLab offers documentation to guide you through the process. You can find valuable resources in GitLab's [official documentation](https://docs.gitlab.com/ee/ci/migration/jenkins.html).\n\nIn addition to documentation, GitLab's Professional Services team is available to assist organizations in their migrations. They bring expertise and experience to ensure a smooth transition. Whether it's understanding the nuances of Jenkinsfile to .gitlab-ci.yml conversion or optimizing your CI/CD workflows, their support can be invaluable.\n\n> Try GitLab CI/CD today with [a free trial of Ultimate](https://gitlab.com/-/trials/new).\n",[827,279,717,233,9,1299],{"slug":2659,"featured":6,"template":698},"jenkins-gitlab-ultimate-guide-to-modernizing-cicd-environment","content:en-us:blog:jenkins-gitlab-ultimate-guide-to-modernizing-cicd-environment.yml","Jenkins Gitlab Ultimate Guide To Modernizing Cicd Environment","en-us/blog/jenkins-gitlab-ultimate-guide-to-modernizing-cicd-environment.yml","en-us/blog/jenkins-gitlab-ultimate-guide-to-modernizing-cicd-environment",{"_path":2665,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2666,"content":2672,"config":2677,"_id":2679,"_type":14,"title":2680,"_source":16,"_file":2681,"_stem":2682,"_extension":19},"/en-us/blog/jenkins-to-gitlab-migration-made-easy",{"title":2667,"description":2668,"ogTitle":2667,"ogDescription":2668,"noIndex":6,"ogImage":2669,"ogUrl":2670,"ogSiteName":686,"ogType":687,"canonicalUrls":2670,"schema":2671},"Jenkins-to-GitLab migration made easy","Learn why and how to migrate from Jenkins to GitLab with ease by following this step-by-step guide.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663019/Blog/Hero%20Images/AdobeStock_519147119.jpg","https://about.gitlab.com/blog/jenkins-to-gitlab-migration-made-easy","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Jenkins-to-GitLab migration made easy\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Fernando Diaz\"}],\n        \"datePublished\": \"2024-02-01\",\n      }",{"title":2667,"description":2668,"authors":2673,"heroImage":2669,"date":2674,"body":2675,"category":10,"tags":2676},[1533],"2024-02-01","GitLab is the most comprehensive AI-powered DevSecOps platform. This means\nthat GitLab provides everything needed to plan, develop, and deliver secure\nsoftware faster, all within one tool.\n\n\nPlatforms take away the pains and struggles of integrating various tools\n(DIY DevOps) to enable the software development lifecycle (SDLC). Since\nJenkins is not a platform, additional tools are required to complete the\nSDLC. This DIY DevOps approach introduces toolchain complexity, which\ncreates the following drawbacks:\n\n\n- Custom support is required for the integration and orchestration of tools\n\n- Difficulty maintaining/upgrading/securing separate tools\n\n- Inefficiency in measuring organizational transformation\n\n- Poor developer experience\n\n- Additional management/time/budget costs\n\n- Loss of productivity\n\n- Context switching and collaboration inefficiencies\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752175993/Blog/ikr97sr9jclddeqdg7ew.png\" alt=\"Import project selection\">\n   \u003Cfigcaption>DIY DevOps vs. DevSecOps Platform\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\nFor these reasons, many Jenkins teams are considering migrating to a\nDevSecOps platform. If you are looking for a more powerful, reliable, and\nsecure solution, GitLab is your best option! GitLab is free to get started\nwith and offers different subscription tiers based on the needs of your\norganization. To learn more about our offerings and features, check out our\n[pricing page](https://about.gitlab.com/pricing/).\n\n\nIn this blog, you will learn:\n\n- How to plan for a migration\n\n- How to migrate repositories from other source code management (SCM) tools\nto GitLab\n\n- How to migrate CI/CD pipelines from Jenkins to GitLab\n\n- Additional migration considerations\n\n\n### Planning for a migration\n\n\nBefore starting a migration from another tool to GitLab CI/CD, you should\nbegin by developing a migration plan. A migration plan is an important\ntechnical step for setting expectations. CI/CD tools differ in approach,\nstructure, and technical specifics, meaning that migrations are not just 1:1\nmappings of data. A migration plan will provide the following benefits:\n\n- Sets and communicates a clear vision of what your migration goals are,\nwhich helps your users understand why the effort is worth it. The value is\nclear when the work is done, but people need to be aware while it’s in\nprogress too.\n\n- Provides sponsorship and alignment from the relevant leadership teams\nhelps with the point above.\n\n- Spends time educating users on what’s different.\n\n- Finds ways to sequence or delay parts of the migration and prevent\nnon-migrated (or partially migrated) states for too long.\n\n- Documents advantages of the improvements that GitLab CI/CD offers, and\nupdates your implementation as part of the transition.\n\n\nA migration plan will allow you to put a process in place where you can\nslowly migrate to GitLab with minimal disruption. This may include running\nboth Jenkins and GitLab, while certain projects are moved to GitLab and\noffloaded from Jenkins.\n\n\n### Defining a change management process\n\n\nThe migration plan should define an effective change management process.\nDevelopers, IT Operations, Cloud Administrators, Security, and Quality\nEngineers may not have experience with GitLab and they may not know why you\nor your leadership have decided to move in this direction.\n\n\nThe people this is impacting need to know:\n\n- __Why__ the change is being made\n\n- __What__ the future state looks like\n\n- __How__ the company intends to get there from here\n\n- __Where__ to go for more information or help \n\n\nTo this end, you should consider the following steps to manage change across\nthese functional roles: \n\n- __Analyze the current state__: Document the current state of processes.\nGather metrics as a baseline. Identify what's working and not working with\nCI/CD by interviewing key team members. Document the challenges you uncover\nboth quantitatively and qualitatively. You’re going to have to sell the\nvision and reason for the change, so the more clearly you can define the\nproblem set, the easier it will be to gain buy-in from across the business. \n\n- __Establish a vision__: Now that you have current pain points outlined\nquantitatively with baseline metrics and qualitatively (in the words of your\nteam members), communicate a vision of the future state. Explain why it's\nimportant (tie this to business success metrics). Provide live and recorded\ndemonstrations of what good looks like and compare it to the current state.\nReinforce this message through multiple channels and media — chat groups,\nall-hands meetings, email notifications, banner notifications on GitLab,\netc.\n\n- __Educate the workforce__: Invest in [GitLab CI/CD\nTraining](https://about.gitlab.com/services/education/gitlab-ci/) delivered\nby a GitLab expert. Measure knowledge acquisition and retention using\n[GitLab Certifications](https://levelup.gitlab.com/pages/certifications). \n\n- __Communicate roadmap and resources__: Communicate to your team members\nthe intended timeline, available resources to help them transition, and\ncommunity resources like chat groups, Q&A boards, or GitLab Influencer\noffice hours so they can ask questions and get help. Bonus points for\nbuilding a reward system to incentivize teams to transition early and share\ntheir experience with their peer application groups!\n\n\nIf you have these elements in place as you begin this transition, you will\nhave a framework for success. \n\n\n### Establishing migration goals\n\nBefore performing a migration, you should have a good understanding of your\ngoals and how to meet them. For example, some questions you should have\nanswers to are as follows:\n\n- What is your timeline to migrate?\n\n- How is your Jenkins server currently configured?\n\n- How many projects must be migrated?\n\n- What is the complexity of your pipeline?\n\n- Does it require external dependencies, multiple pipeline triggers,\nparallel builds, etc.?\n\n- How/Where do you deploy your code?\n\n- What is the release/review process for deploying code?\n\n- Is it integrated into Jenkins, or a separate workflow triggered by\nJenkins?\n\n- Which build artifacts or binaries are required for pipeline success?\n\n- Which plugins are used by jobs in Jenkins today?\n\n- Which software is installed on the Jenkins agents?\n\n- What SCM solution are you currently using?\n\n- Are there any shared libraries in use within your Jenkins jobs?\n\n- Which authentication method is used for Jenkins (Basic auth, LDAP/AD,\nSSO)?\n\n- Are there other projects that you need to access from your pipeline?\n\n- Are there credentials in Jenkins used to access outside services?\n\n\nBy answering these questions you’ll know how to proceed with the migration,\nhow long it will take, and where to start. Once you have built a plan and\nare confident of the expectations and possible pitfalls, you can begin the\nmigration process.\n\n\n### Prerequisites for migration\n\nOnce you have created a migration plan and addressed all the expectations of\nthe migration, you can begin to set up GitLab. Some of the prerequisites\nsuggested for migration are as follows:\n\n- Get familiar with GitLab. Read about the [key GitLab CI/CD\nfeatures](https://docs.gitlab.com/ee/ci/index.html).\n\n- Follow tutorials to create your first [GitLab\npipeline](https://docs.gitlab.com/ee/ci/quick_start/index.html) and [more\ncomplex pipelines](https://docs.gitlab.com/ee/ci/quick_start/tutorial.html)\nthat build, test, and deploy a static site.\n\n- Review the [.gitlab-ci.yml keyword\nreference](https://docs.gitlab.com/ee/ci/yaml/index.html).\n\n- Set up and configure GitLab.\n\n- Test your GitLab instance.\n\n\nOnce you understand GitLab and an instance has been configured, you can work\nthrough your migration plan and begin to move projects from Jenkins over to\nGitLab. Make sure your GitLab instance has been properly set up using GitLab\nbest practices and [reference\narchitectures](https://docs.gitlab.com/ee/administration/reference_architectures/).\n\n\n### Migrating repositories to GitLab\n\nOne of the main drawbacks of Jenkins is that it does not provide an SCM\nsolution. If you are using Jenkins, your code must be stored in a separate\nSCM solution which Jenkins must have access to. Because GitLab has built-in\nSCM, migrating away from Jenkins also allows you to migrate from the SCM\nsolution you were leveraging, bringing forth an additional reduction in\ncosts.\n\n\nGitLab provides tools to allow you to easily move your repository and its\nmetadata into GitLab. The following importers are included to assist in\nmigrating your projects to GitLab:\n\n\n- [GitHub](https://docs.gitlab.com/ee/user/project/import/github.html)\n\n- [Another GitLab\ninstance](https://docs.gitlab.com/ee/user/project/settings/import_export.html)\n\n- [Bitbucket\nCloud](https://docs.gitlab.com/ee/user/project/import/bitbucket.html)\n\n- [Bitbucket\nServer](https://docs.gitlab.com/ee/user/project/import/bitbucket_server.html)\n\n- [FogBugz](https://docs.gitlab.com/ee/user/project/import/fogbugz.html)\n\n- [Gitea](https://docs.gitlab.com/ee/user/project/import/gitea.html)\n\n- [Jira (Issues\nonly)](https://docs.gitlab.com/ee/user/project/import/jira.html)\n\n- [Repo by manifest\nfile](https://docs.gitlab.com/ee/user/project/import/manifest.html)\n\n- [Repo by\nURL](https://docs.gitlab.com/ee/user/project/import/repo_by_url.html)\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176002/Blog/ie2xrexhbcoq6m8rnhit.png\" alt=\"GitHub to GitLab Repo Exporter\">\n   \u003Cfigcaption>GitHub to GitLab Repo Exporter\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\nEach importer imports different data from a project. Read the [import and\nmigrate projects\ndocumentation](https://docs.gitlab.com/ee/user/project/import/) to learn\nmore about the provided importers to see what data is migrated to GitLab.\nAdditionally, you can [automate group and project\nimport](https://docs.gitlab.com/ee/user/project/import/#automate-group-and-project-import)\nand build a custom solution to further suit the needs of your organization:\n\n\n- [Professional Services](https://about.gitlab.com/services/)\n\n- [Migration\nUtilities](https://gitlab.com/gitlab-org/professional-services-automation/tools/migration/congregate/-/blob/master/docs/using-congregate.md#quick-start)\n\n- [Frequently Asked Migration\nQuestions](https://gitlab.com/gitlab-org/professional-services-automation/tools/migration/congregate/-/blob/master/customer/famq.md)\n\n\n### How to migrate a repository\n\nMigrating a repository to GitLab is easy using our built-in importers. In\nthis example, I’ll show how to copy a repo from GitHub to GitLab along with\n[its\nresources](https://docs.gitlab.com/ee/user/project/import/github.html#imported-data)\n(Issues, Pull Requests, Milestones, etc.). In order to migrate a repository\nfrom another GitHub to GitLab, you can follow the steps below:\n\n\n1. On the left sidebar, at the top, select **Create new (+)**.\n\n2. Select **New project/repository** under the In GitLab section.\n\n3. Select **Import project**.\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176017/Blog/boowmmaqhbredxa3g92s.png\" alt=\"Import project selection\">\n   \u003Cfigcaption>Import project selection\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\n4. Click the **GitHub** button.\n    - If using GitLab self-managed, then you must [enable the GitHub importer](https://docs.gitlab.com/ee/administration/settings/import_and_export_settings.html#configure-allowed-import-sources).\n    - Note that other importers can be initiated in the same way.\n5. Now you can either:\n    - Authorize with GitHub OAuth: Select **Authorize with GitHub**.\n    - Or, use a GitHub personal access token:\n       - Go to [https://github.com/settings/tokens/new](https://github.com/settings/tokens/new).\n       - In the **Note** field, enter a token description.\n       - Select the repo scope.\n       - Optionally to import collaborators, select the              **read:org** scope.\n       - Click the **Generate token** button.\n       - On the GitLab import page, in the Personal Access Token field, paste the GitHub personal access token.\n6. Click the **Authenticate** button.\n\n7. Select the items you wish to migrate.\n\n8. Select the projects you wish to migrate and to where.\n\n9. Press the **Import** button.\n\n\nNow you should have the imported project in your workspace. For additional\nguidance on migrating from GitHub to GitLab you can watch this video:\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/0Id5oMl1Kqs?si=TQ5HI9aMwtzJMiMi\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\nOnce you have completed the repository migration, you can set your Jenkins\npipeline to leverage the Jenkinsfile within GitLab. This can be done by\nsetting the repository URL via to your newly imported project via the Jenkin\npipeline configuration menu:\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176020/Blog/mu475liw66abcxbu2g6g.png\" alt=\"Jenkins Pipeline SCM settings\">\n   \u003Cfigcaption>Jenkins Pipeline SCM settings\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\nThis is useful for the initial repo migration phase and allows you to use\nboth Jenkins and GitLab in parallel, preventing service disruptions while\nyou work on migrating the CI/CD functionality.\n\n\nAdditionally, you can leverage the [GitLab Jenkins\nplugin](https://plugins.jenkins.io/gitlab-plugin/) to assist with migration.\nThis plugin allows GitLab to trigger and obtain the status of Jenkins\nbuilds.\n\n\n### Migrating CI/CD pipelines\n\nOnce you have migrated your repositories to GitLab, you can proceed to\nmigrate your Jenkins pipelines to GitLab. This process can be fairly\nstraightforward, but requires an understanding of both Jenkins and GitLab\nconcepts and syntax.\n\n\nJenkins provides two different types of syntax for defining pipelines,\nDeclarative and Scripted. In this guide we will be covering migrating from\nDeclarative pipelines since they are the most commonly used.\n\n\n### Step-by-step pipeline migration\n\nIn this tutorial we will analyze a Jenkinsfile (Groovy) alongside a GitLab\nCI/CD configuration file (YAML) that builds, tests, and deploys a\nmicroservice written in Golang. We will then proceed to enable the pipeline\nwithin GitLab and see its results. The pipeline will:\n\n\n- Use the golang container image with the **alpine** tag\n\n- Run a job for building the Golang code into an executable binary\n   - Stores the built executable as an artifact\n- Run a job to run unit tests\n\n- Run a job to deploy to staging\n   - Only executes if the commit targets the **staging** branch\n   - Starts after the **test** stage succeeds\n   - Uses the built executable artifact from the earlier job\n\nBelow you can see Jenkins and GitLab pipeline definitions along with\ndescriptive comments. You can see the pipeline in action in the [Meow\nMigration\nproject](https://gitlab.com/gitlab-de/projects/blogs/meow-migration).\n\n\nLet's take a look at a Jenkinsfile written in Groovy:\n\n\n```  \n\n// The top-level of the declarative\n\n// pipeline.\n\npipeline {\n\n  // Defines the default agent to use\n  // when it is not explicitly defined\n  // in a job.\n    agent any\n\n  // Defines the stages that will run\n  // in numerical order. Each stage\n  // only runs one job.\n    stages {\n\n    // Defines the name of the stage\n        stage('build') {\n      // Defines the container image to\n      // use for this job, overwriting\n      // the default 'agent any'.\n      // The Jenkins Docker plugin\n      // must be configured for this\n      // to run.\n            agent { docker 'golang:alpine' }\n\n      // Defines the sequence of steps\n      // to execute when the stage is\n      // run.\n            steps {\n                sh 'go build -o bin/meow-micro'\n                sh 'chmod +x bin/meow-micro'\n            }\n\n      // The steps to run after the\n      // stage completes.\n            post {\n              always {\n\n        // Stores the stage artifacts\n        // generated for use in another\n        // job.\n                archiveArtifacts artifacts: 'bin/meow-micro'\n                onlyIfSuccessful: true\n              }\n            }\n        }\n\n    stage('test') {\n            agent { docker 'golang:alpine' }\n            steps {\n                sh 'go test .'\n            }\n        }\n\n        stage('deploy') {\n      // Defines conditions which must\n      // be met in order for the job to\n      // execute. In this case the\n      // deploy job will only run on the \n      // staging branch.\n            when {\n              branch 'staging'\n            }\n            steps {\n                echo 'Deploying meow-micro to staging'\n        // Uses the artifact stored in\n        // the build stage.\n                sh './bin/meow-micro'\n            }\n        }\n    }\n}\n\n```\n\n\nNow, let's see how to create the same functionality in GitLab:\n\n\n```\n\n# Defines the default image to use\n\n# when it is not explicitly defined in\n\n# a job.\n\ndefault:\n  image: alpine:latest\n\n# Defines the order to run the stages.\n\n# Each stage can have multiple jobs.\n\nstages:\n  - build\n  - test\n  - deploy\n\n# Defines the name of the job\n\ncreate-binary:\n # Defines the stage the job will run in\n  stage: build\n # Defines the container image to use\n # for this job, overwriting default.\n  image: golang:alpine\n # Defines the sequence of steps to\n # execute when the job is run.\n  script:\n    - go build -o bin/meow-micro\n    - chmod +x bin/meow-micro\n # Stores the job artifacts generated\n # for use in another job.\n  artifacts:\n    paths:\n      - bin/meow-micro\n    expire_in: 1 week\n\nunit-tests:\n  stage: test\n  image: golang:alpine\n  script:\n    - go test .\n # Defines commands to run after the\n # job.\n after_script:\n  - echo \"Tests Complete\"\n\nstaging-deploy:\n  stage: deploy\n # Defines commands to run before the\n # actual job.\n  before_script:\n    - apk update\n  script:\n    - echo \"Deploying meow-micro to staging environment\"\n    - ./bin/meow-micro\n # Defines conditions which must be met\n # in order for this job to execute. In\n # this case the staging-deploy job will \n # only run on the staging branch.\n  rules:\n    - if: $CI_COMMIT_BRANCH == 'staging'\n # Allows the artifact stored in the\n # build job to be used in this job.\n  artifacts:\n    paths:\n      - bin/meow-micro\n```\n\n\nAs you may have observed, there are many similarities between both Jenkins\nand GitLab in terms of syntax, making pipeline migration straightforward.\nWhile the above provides a basic example, be sure to read the comprehensive\nlist of [feature and concept\ncomparisons](https://docs.gitlab.com/ee/ci/migration/jenkins.html#comparison-of-features-and-concepts)\nbetween both tools.\n\n\nNow that we have an understanding of how to map Jenkins to GitLab we can\nstart creating a pipeline with the same functionality in GitLab. In order to\nperform the migration of CI/CD, you can go through the following steps:\n\n\n##### 1. Open the repository you migrated to GitLab in the section above.\n\n- On the left sidebar, at the top, select **Search or go to…**.\n\n- Locate your project.\n\n\n##### 2. Open the [Pipeline\nEditor](https://docs.gitlab.com/ee/ci/pipeline_editor/).\n\n- On the left sidebar, Select **Build > Pipeline editor**.\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176026/Blog/ecp4jh7epho2oxuegaor.png\" alt=\"Pipeline editor menu\">\n   \u003Cfigcaption>Pipeline editor menu\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\n- Click the **Configure pipeline** button.\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176029/Blog/nypfh01zhwgvzqc0xz3v.png\" alt=\"Configure pipeline selection\">\n   \u003Cfigcaption>Configure pipeline selection\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\n##### 3. Populate the [.gitlab-ci.yml](https://docs.gitlab.com/ee/ci/yaml/).\n\n- Add the GitLab CI pipeline code. \n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176031/Blog/nxi6uxxispyyoiiyvxyg.png\" alt=\"Pipeline editor input\">\n   \u003Cfigcaption>Pipeline editor input\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\n- Verify that the syntax is correct.\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176037/Blog/x3d4utfsnymye0lvphtf.png\" alt=\"Pipeline syntax validation\">\n   \u003Cfigcaption>Pipeline syntax validation\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\n- Visualize the pipeline.\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176043/Blog/hipzofpyywjxf62edzfv.png\" alt=\"Pipeline visualization\">\n   \u003Cfigcaption>Pipeline visualization\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\n##### 4. Commit the file to the main branch.\n\n- Add a commit message.\n\n- Make sure the branch is set to main.\n\n- Click the Commit changes button.\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176048/Blog/nn8bl7rdysabccoycfrk.png\" alt=\"Commit changes dialog\">\n   \u003Cfigcaption>Commit changes dialog\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\nOnce the file has been merged, the defined pipeline will kick off. You can\ngo back to your project and [view the\npipeline](https://docs.gitlab.com/ee/ci/pipelines/#view-pipelines) in action\nby selecting it under your project’s **Build > Pipelines** page. Since it\nwas run on the **main** branch, you will see only the **create-binary** and\nunit-tests jobs; the **staging-deploy** job only runs on the staging branch.\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176051/Blog/wfb4k8nkzpg28kpf2pzz.png\" alt=\"Pipeline running on main branch\">\n   \u003Cfigcaption>Pipeline running on main branch\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\nIf we create a staging branch, we can see that the following pipeline is\ninitiated.\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176053/Blog/e2jxedpolaniotgixpby.png\" alt=\"Pipeline running on staging branch\">\n   \u003Cfigcaption>Pipeline running on staging branch\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\nWhen clicking on a job we can see its output:   \n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176056/Blog/fywzwbzkwcvc9zzakilh.png\" alt=\"create-binary job output\">\n   \u003Cfigcaption>create-binary job output\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176061/Blog/ekmpd8ecanwwiena9xi9.png\" alt=\"unit-tests job output input\">\n   \u003Cfigcaption>unit-tests job output input\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\n\u003Ccenter>\n\n\u003Cfigure>\n   \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176065/Blog/h7nqxszy50xdmnvhalfq.png\" alt=\"staging-deploy job output\">\n   \u003Cfigcaption>staging-deploy job output\u003C/figcaption>\n\u003C/figure>\n\n\u003C/center>\n\n\u003Cp>\u003C/p>\n\n\nYou can see how the artifact is stored in the create-binary job and used in\nthe staging-deploy job. And that's how easy it is to migrate a pipeline from\nJenkins to GitLab!\n\n\n### Additional considerations when migrating\n\nSome helpful considerations we’ve found to make the deployment process more\nstraightforward are as follows:\n\n\n- Don't try to replicate tasks into GitLab jobs 1:1. Take some inventory and\ntime to understand what the current pipeline is doing, and which problem it\nis solving.\n\n\n- Some Jenkins jobs may be too complex to move over to GitLab right away.\nFor this reason, it may be beneficial to use the [GitLab Jenkins\nplugin](https://plugins.jenkins.io/gitlab-plugin/) to initiate Jenkins\npipelines and view their results directly from GitLab. This allows you to\nslowly migrate certain actions to GitLab until the whole pipeline can be\nmoved.\n\n\n- Implement [security scanners and code\nquality](https://docs.gitlab.com/ee/user/application_security/) using\nbuilt-in templates provided by GitLab from the start. This will allow you to\nshift security left, reducing the potential for a breach.\n\nDon't overcomplicate the CI/CD config and try to use every feature advantage\nat once. Modularize code and implement it in small iterations.\n\n\n- Implement monitoring and governance from the start.\n\n\n- Understand that the GitLab Runner (Go) might behave differently than the\nJenkins agent (Java). CPU usage and memory consumption might differ — make\nsure to compare over time.\n\n\n- Consider investing in auto-scaling mechanisms, and shut down unneeded\nresources on the weekend, or outside of working hours.\n\n\n- Modernize application development by containerizing your jobs. Jenkins\njobs are not executed on a container today but on a Jenkins agent running as\na VM.\n\n\nWhile this list is not exhaustive, it does provide a good start on some\nconsiderations to take note of. If you need additional help, GitLab provides\n[professional services](https://about.gitlab.com/get-help/) to support your\nmigration journey.\n\n\n### Learn more\n\nThanks for reading! I hope this guide has helped you get a clear\nunderstanding of why and how to migrate from Jenkins to GitLab. Not\nconvinced? [Give GitLab a try with our free\ntrial](https://about.gitlab.com/free-trial/), and see the value of a\nDevSecOps platform!\n\n\nHere are a few resources where you can learn more about GitLab, the benefits\nof using a DevSecOps platform, and migrating from Jenkins:\n\n\n- [Migrating from\nJenkins](https://docs.gitlab.com/ee/ci/migration/jenkins.html)\n\n- [Planning a\nmigration](https://docs.gitlab.com/ee/ci/migration/plan_a_migration.html)\n\n- [GitLab Project\nImporters](https://docs.gitlab.com/ee/user/project/import/)\n\n- [Tutorial: GitHub to GitLab migration the easy\nway](https://about.gitlab.com/blog/github-to-gitlab-migration-made-easy/)\n\n- [Video: GitHub to GitLab migration the easy\nway](https://youtu.be/0Id5oMl1Kqs?feature=shared)\n\n- [Jenkins to GitLab: The ultimate guide to modernizing your CI/CD\nenvironment](https://about.gitlab.com/blog/jenkins-gitlab-ultimate-guide-to-modernizing-cicd-environment/)\n",[109,9],{"slug":2678,"featured":91,"template":698},"jenkins-to-gitlab-migration-made-easy","content:en-us:blog:jenkins-to-gitlab-migration-made-easy.yml","Jenkins To Gitlab Migration Made Easy","en-us/blog/jenkins-to-gitlab-migration-made-easy.yml","en-us/blog/jenkins-to-gitlab-migration-made-easy",{"_path":2684,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2685,"content":2691,"config":2696,"_id":2698,"_type":14,"title":2699,"_source":16,"_file":2700,"_stem":2701,"_extension":19},"/en-us/blog/keeping-your-development-dry",{"title":2686,"description":2687,"ogTitle":2686,"ogDescription":2687,"noIndex":6,"ogImage":2688,"ogUrl":2689,"ogSiteName":686,"ogType":687,"canonicalUrls":2689,"schema":2690},"DRY development: A cheatsheet on reusability throughout GitLab","How to follow the DevOps principle of 'don't repeat yourself' to optimize CI/CD.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683555/Blog/Hero%20Images/drylights.jpg","https://about.gitlab.com/blog/keeping-your-development-dry","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"DRY development: A cheatsheet on reusability throughout GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Noah Ing\"},{\"@type\":\"Person\",\"name\":\"Joe Randazzo\"}],\n        \"datePublished\": \"2023-01-03\",\n      }",{"title":2686,"description":2687,"authors":2692,"heroImage":2688,"date":2693,"body":2694,"category":909,"tags":2695},[821,2499],"2023-01-03","More than 20 years ago, the book [The Pragmatic\nProgrammer](https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edition/)\nbrought attention to the DRY principle, or “Don’t Repeat Yourself.\" This\nprinciple is defined as every piece of knowledge must have a single,\nunambiguous, authoritative representation within a system.\n\n\nThe main problem to solve here is minimizing duplication. As a development\nproject is bombarded with new requests or changing requirements, DevOps\nteams must balance between development of net-new features or maintaining\nexisting code. The important part is how to reduce duplicate knowledge\nacross projects.\n\n\nThis tutorial explores the mechanisms throughout GitLab that leverage the\nDRY principle to cut down on code duplication and standardize on knowledge.\nTo see working examples of reusability in action, take a look at this\n[repository](https://gitlab.com/guided-explorations/gitlab-ci-yml-tips-tricks-and-hacks/dry-repository-a-cheatsheet).\n\n\n## Minimizing duplication in CI/CD\n\n\n### include\n\n[`include`](https://docs.gitlab.com/ee/ci/yaml/index.html#include) can be\nused to transform a single .gitlab-ci.yml file into multiple files to\nimprove readability and minimize duplication. For example, testing,\nsecurity, or deployment workflows can be broken out into separate templates.\nThis also allows\n[ownership](https://docs.gitlab.com/ee/user/project/codeowners/) of the\nfiles.\n\n\n\n```yaml\n\ninclude:\n  - template: CI/Build.gitlab-ci.yml\n  - template: CI/Test.gitlab-ci.yml\n  - template: CI/Security.gitlab-ci.yml\n  - template: CD/Deploy.gitlab-ci.yml\n\n```\n\n\n### YAML anchors\n\n[YAML\nanchors](https://docs.gitlab.com/ee/ci/yaml/yaml_optimization.html#anchors)\ncan be used to reduce repeat syntax and extend blocks of CI workflow,\nincluding jobs, variables, and scripts.\n\n\n```yaml\n\n.test_template: &test_suite\n  image: ruby:2.6\n\nunit_test:\n  \u003C\u003C: *test_suite\n  script:\n    - echo \"Running a test here\"\n\nend_to_end_test:\n  \u003C\u003C: *test_suite\n  script:\n    - echo \"Running a test here\"\n\nsmoke_test:\n  \u003C\u003C: *test_suite\n  script:\n    - echo \"Running a test here\"\n```\n\n\n### extends\n\n[`extends`](https://docs.gitlab.com/ee/ci/yaml/index.html#extends) is\nsimilar to anchors with additional flexibility and readability. The major\ndifference is it can be used with `includes`.\n\n\n```yaml\n\n\n.prepare_deploy:\n  stage: deploy\n  script:\n    - echo \"I am preparing the deploy\"\n  only:\n    - main\n\ndeploy_to_dev:\n  extends: .prepare_deploy\n  script:\n    - echo \"Deploy to dev environment\"\n  environment: dev\n\ndeploy_to_production:\n  extends: .prepare_deploy\n  script:\n    - echo \"Deploy to production environment\"\n  when: manual\n  environment: production\n```\n\n\n### !reference\n\n[`!reference`](https://docs.gitlab.com/ee/ci/yaml/yaml_optimization.html#reference-tags)\nenables the selection of keyword configuration from other job sections and\nreuse in the current session.\n\n\n```yaml\n\n.vars:\n  variables:\n    DEV_URL: \"http://dev-url.com\"\n    STAGING_URL: \"http://staging-url.com\"\n\n.setup_env:\n  script:\n    - echo \"Creating Environment\"\n\n.teardown_env:\n  after_script:\n    - echo \"Deleting Environment\"\n\nintegration_test:\n  variables: !reference [.vars, variables, DEV_URL]\n  script:\n    - !reference [.setup_env, script]\n    - echo \"Run Test\"\n  after_script:\n    - !reference [.teardown_env, after_script]\n\nperformance_test:\n  variables: !reference [.vars, variables]\n  script:\n    - !reference [.setup_env, script]\n    - echo \"Run Test\"\n  after_script:\n    - !reference [.teardown_env, after_script]\n```\n\n\n### Downstream pipelines\n\n[Downstream\npipelines](https://docs.gitlab.com/ee/ci/pipelines/downstream_pipelines.html)\nenable the breakout of microservices and their pipelines. A .gitlab-ci.yml\nfile can be used for each service, and when a file or directory is changed,\nonly that pipeline needs to be triggered improving the awareness and\nreadability of what’s deploying.\n\n\n```yaml\n\nui:\n  trigger:\n    include: ui/.gitlab-ci.yml\n    strategy: depend\n  rules:\n    - changes: [ui/*]\n\nbackend:\n  trigger:\n    include: backend/.gitlab-ci.yml\n    strategy: depend\n  rules:\n    - changes: [backend/*]\n```\n\n\n![Dynamic child\npipeline](https://about.gitlab.com/images/blogimages/2022-02-01-parent-child-vs-multi-project-pipelines/parent-child.png){:\n.shadow}\n\n\n### CI/CD variables\n\n[CI/CD variables](https://docs.gitlab.com/ee/ci/variables/) can be scoped to\na specific level, including the project, group, instance level, or\n.gitlab-ci.yml level. The values can be stored and reused across a group for\nproject inheritance or overwritten at the project level.\n\n\n```yaml\n\nvariables:\n  PROJECT_LEVEL_VARIABLES: \"I am first in line in precedence\"\n  GROUP_LEVEL_VARIABLES: \"I am second in line\"\n  INSTANCE_LEVEL_VARIABLES: \"I am in third place\"\n  GITLAB_CI_YML_LEVEL_VARIABLES: \"I am last in line of precedence\"\n\n```\n\n\n## Creating consistent code reviews across multiple teams\n\n\n### Description templates\n\n[Description\ntemplates](https://docs.gitlab.com/ee/user/project/description_templates.html)\nenable teams to define a consistent workflow for issues or merge requests.\nFor example, the MR template can define a checklist for rolling out to a\nfeature to ensure it’s documented, quality tested, and reviewed by\nappropriate team members. Here are [MR\ntemplates](https://gitlab.com/gitlab-org/gitlab/-/tree/master/.gitlab/merge_request_templates)\nthat GitLab team members use daily.\n\n\n```md\n\n\u003C!-- These templates can be set at the instance or group level to share\namongst the organization:\nhttps://docs.gitlab.com/ee/user/project/description_templates.html#set-instance-level-description-templates\n-->\n\n\n## What does this MR do?\n\n\n\u003C!-- Briefly describe what this MR is about. -->\n\n\n## Related issues\n\n\n\u003C!-- Link related issues below. -->\n\n\n## Create a checklist for the author or reviewer\n\n- [ ] Optional. Consider taking this writing course before publishing a\nchange.\n\n- [ ] Follow the documentation process stated here.\n\n- [ ] Tag this user group if this applies.\n\n\n\n\u003C!-- Quick Actions - See\nhttps://docs.gitlab.com/ee/user/project/quick_actions.html#issues-merge-requests-and-epics\nfor a list of all the quick actions available. -->\n\n\n\u003C!-- Add a label to assign a specific workflow using scoped labels -->\n\n/label ~documentation ~\"type::maintenance\" ~\"docs::improvement\"\n~\"maintenance::refactor\"\n\n\n\u003C!-- Apply draft format automatically -->\n\n/draft\n\n\n\u003C!-- Assign myself or a usergroup -->\n\n/assign me\n\n```\n\n\n### Project templates\n\n[Project\ntemplates](https://docs.gitlab.com/ee/user/group/custom_project_templates.html)\ncan be used to define an initial project structure for when new services are\nbeing developed. This gives a consistent starting point for projects that\ncome equipped with the latest file configurations and defaults.\n\n\n### File templates\n\n[File\ntemplates](https://docs.gitlab.com/ee/administration/settings/instance_template_repository.html)\nare similar to project templates but are default files to choose from when\nadding a new file to your repository. The team then can quickly choose from\nfiles that have best practices baked in and organization defaults.\n\n\n## Defining a Pipeline Center of Excellence project for CI/CD workflows\n\n\nAs you 'productionize' your CI/CD workflows, it’s recommended to create a\n“Pipeline Center of Excellence” project that contains templates, containers,\nor other abstracted constructs that can be adopted throughout the\norganization. This project contains file or CI/CD templates that have the\nbest practices or well-formed workflows defined for development teams to\nquickly adopt (includes) without recreating the wheel. To explore this in\npractice, visit [Pipeline\nCOE](https://gitlab-org.gitlab.io/professional-services-automation/pipelinecoe/pipeline-templates/#/)\ndocumentation written by the GitLab Professional Services team.\n\n\nHave a reusable component to suggest or that we missed? Add a comment to\nthis blog post or suggest a change to this file!\n\n\n## Related posts\n\n- [How to keep up with CI/CD best\npractices](https://about.gitlab.com/blog/how-to-keep-up-with-ci-cd-best-practices/)\n\n- [How to become more productive with GitLab\nCI](https://about.gitlab.com/blog/how-to-become-more-productive-with-gitlab-ci/)\n\n- [A visual guide to GitLab CI/CD\ncaching](https://about.gitlab.com/blog/a-visual-guide-to-gitlab-ci-caching/)\n\n\nCover image by [Federico\nBeccari](https://unsplash.com/@federize?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\non [Unsplash](https://www.unsplash.com).\n",[825,826,1299,9],{"slug":2697,"featured":6,"template":698},"keeping-your-development-dry","content:en-us:blog:keeping-your-development-dry.yml","Keeping Your Development Dry","en-us/blog/keeping-your-development-dry.yml","en-us/blog/keeping-your-development-dry",{"_path":2703,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2704,"content":2710,"config":2715,"_id":2717,"_type":14,"title":2718,"_source":16,"_file":2719,"_stem":2720,"_extension":19},"/en-us/blog/kingfisher-transforming-the-developer-experience-with-gitlab",{"title":2705,"description":2706,"ogTitle":2705,"ogDescription":2706,"noIndex":6,"ogImage":2707,"ogUrl":2708,"ogSiteName":686,"ogType":687,"canonicalUrls":2708,"schema":2709},"Kingfisher transforming the developer experience with GitLab","Learn how the international company focuses on DevSecOps, including automation, to reduce complexity in workflows for better efficiency.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659756/Blog/Hero%20Images/REFERENCE_-_display_preview_for_blog_images.png","https://about.gitlab.com/blog/kingfisher-transforming-the-developer-experience-with-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Kingfisher transforming the developer experience with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sharon Gaudin\"}],\n        \"datePublished\": \"2024-11-12\",\n      }",{"title":2705,"description":2706,"authors":2711,"heroImage":2707,"date":2712,"body":2713,"category":972,"tags":2714},[756],"2024-11-12","Kingfisher plc, an international home improvement company, has leaned into GitLab’s end-to-end platform to help it build a DevSecOps foundation that is revolutionizing its developer experience. And the company plans to continue that improvement by increasing its use of platform features, focusing on security, simplifying its toolchain, and increasing the use of automation.\n\n> \u003Cimg align=\"left\" width=\"200\" height=\"200\" hspace=\"5\" vspace=\"5\" alt=\"Chintan Parmar\" src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752176076/Blog/ro7u8p695zw9fllbk4j5.png\" style=\"float: left; margin-right: 25px;\"> “The whole point of this is to reduce friction for our engineers, taking away a lot of the complexity in their workflow, and bringing in best practices and governance,” says Chintan Parmar, site reliability engineering manager at Kingfisher. “In terms of what we've done and what we're doing at the moment, it really is about building a foundation in terms of CI/CD and changing the way we deploy to bring in consistency and improve the developer experience.”\n\nParmar talked about his team and their efforts during the [GitLab DevSecOps World Tour event](https://about.gitlab.com/events/devsecops-world-tour/) in London last month. In an on-stage interview with Sherrod Patching, vice president of Customer Success Management at GitLab, he laid out Kingfisher’s journey with the platform, which is enabling its teams, while also making it easier and faster to move software updates and new projects from ideation to deployment.\n\n[Kingfisher](https://www.kingfisher.com/en/index.html) is a parent company with more than 2,000 stores in eight countries across Europe. Listed on the London Stock Exchange and part of the Financial Times Stock Exchange (FTSE) 100 Index, the group reported £13 billion in total revenue in FY 2023/24. Its brands include B&Q, Screwfix, Castorama, and Brico Depot. \n\nThe company first adopted GitLab in 2016, using a free starter license, and then moved to Premium in 2020. In that time, it also has moved from on-premise to a cloud environment, started using shared GitLab runners and source code management, and began building out a CI/CD library that gives team members easy access to standardized and reusable components for typical pipeline stages, such as build, deploy, and test.\n\n## Tracking metrics that execs care about\n\nKingfisher also is tracking metrics, like deployment frequency, lead time to change, and change failure rates, with GitLab. And teams are analyzing value streams, mapping workflows, and finding bottlenecks. All of those metrics are being translated into data that company leaders can sink their teeth into. \n\n“Execs may not care about whether a merge request has been waiting 15 or 20 minutes, but they do care about how we translate that time value into dollars or pounds,” says Parmar, who used GitLab when he previously worked at [Dunelm Group, plc,](https://about.gitlab.com/customers/dunelm/) another major UK-based retailer. “Kingfisher is a very data-driven organization. We are looking to overlay these metrics to see where we can continue to improve our developer experience, eliminating slowdowns and manual tasks, while increasing automation.”\n\nWhile on-stage, Parmar made it clear that all the changes being made are aimed at improving software development and deployment. However, it’s equally paramount to making team members’ jobs easier, giving them more time and autonomy to do the kind of work they enjoy, instead of what can seem like a never-ending stream of repetitive, manual tasks. He noted that the team is so focused on easing workflows and giving engineers more time to be innovative, it has created a “developer experience squad.”\n\n## Putting people first while laying out priorities\n\nSo what’s coming next for Kingfisher and its engineering squads, which have about 600 practitioners?  \n\nAccording to Parmar, Kingfisher already has its priorities mapped out. Using GitLab to [move security left](https://about.gitlab.com/solutions/security-compliance/) is at the top of their list. The group also is focused on continuing to reduce its toolchain, and using automation to increase productivity. And he expects that early in 2025, teams will begin “dabbling” with the artificial intelligence capabilities in [GitLab Duo](https://about.gitlab.com/gitlab-duo/), a suite of AI-powered features in the platform that help increase velocity and solve key pain points across the software development lifecycle. Kingfisher will focus on how that can further increase its efficiency and productivity. \n\nTo get all of this done, Parmar says the first step is to ensure that people come first.\n\n“We’re focused on the hearts and minds of our people... and remembering that people can be attached to how they work through pipelines,” he adds. “People have different ways of building their pipelines. We need to understand what they need, what their workflows look like, and then work with them to find the right solution. After, we’ll go back to them with data that shows the improvements worked. So instead of telling them what they need, we find out what that is, and fix what’s slowing them down. That builds a very good rapport with our engineers.”\n\nChanging how a team creates and deploys software is a journey. Parmar suggests that collaboratively taking developers and security teams on that journey, instead of dragging them along, makes a big difference in ease of migration and in easing team members’ user experience.\n\n> Learn [how other GitLab customers use the DevSecOps platform](https://about.gitlab.com/customers/) to gain results for customers.\n",[974,496,9,1016],{"slug":2716,"featured":91,"template":698},"kingfisher-transforming-the-developer-experience-with-gitlab","content:en-us:blog:kingfisher-transforming-the-developer-experience-with-gitlab.yml","Kingfisher Transforming The Developer Experience With Gitlab","en-us/blog/kingfisher-transforming-the-developer-experience-with-gitlab.yml","en-us/blog/kingfisher-transforming-the-developer-experience-with-gitlab",{"_path":2722,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2723,"content":2728,"config":2733,"_id":2735,"_type":14,"title":2736,"_source":16,"_file":2737,"_stem":2738,"_extension":19},"/en-us/blog/last-year-we-signed-the-secure-by-design-pledge-heres-our-progress",{"title":2724,"description":2725,"ogTitle":2724,"ogDescription":2725,"noIndex":6,"ogImage":1271,"ogUrl":2726,"ogSiteName":686,"ogType":687,"canonicalUrls":2726,"schema":2727},"Last year we signed the Secure by Design pledge - here's our progress","Learn about GitLab's CISA-aligned additions and improvements around MFA, default password reduction, patching, and vulnerability disclosure.","https://about.gitlab.com/blog/last-year-we-signed-the-secure-by-design-pledge-heres-our-progress","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Last year we signed the Secure by Design pledge - here's our progress\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Joseph Longo\"}],\n        \"datePublished\": \"2025-06-09\",\n      }",{"title":2724,"description":2725,"authors":2729,"heroImage":1271,"date":2730,"body":2731,"category":694,"tags":2732},[2616],"2025-06-09","A little over a year go, GitLab signed [CISA’s Secure by Design Pledge](https://about.gitlab.com/blog/secure-by-design-principles-meet-devsecops-innovation-in-gitlab-17/), a directive for technology providers to embed security at the heart of their products from the outset of development. Since then, we've made significant progress towards improving our security posture and creating a more secure ecosystem for our customers to develop secure software faster.\n\n## Meeting the security goals\n\nLet’s explore the additions and improvements we've made to further enhance security across the development lifecycle.\n\n### Multi-factor authentication (MFA)\n\n***Goal: Within one year of signing the pledge, demonstrate actions taken to measurably increase the use of multi-factor authentication across the manufacturer’s products.***\n\nGitLab currently offers multiple [MFA](https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html) options for users to secure their accounts. We also offer SSO functionality to enable [GitLab.com](https://docs.gitlab.com/ee/user/group/saml_sso/), [Self-Managed](https://docs.gitlab.com/integration/saml/), and [GitLab Dedicated](https://docs.gitlab.com/integration/saml/) customers to streamline their authentication processes and their internal MFA requirements.\n\nTo further enhance the platform’s resilience, and to create a more secure foundation for our customers, GitLab is executing a phased MFA by Default rollout.\n\nIn the coming months, we will deploy changes requiring all customers to enable MFA on their accounts. \n\nFor customers who already have MFA enabled or authenticate to GitLab via their organization’s single sign-on (SSO) method, there will be no necessary changes. For customers who do not already have MFA enabled and are not authenticating to GitLab via their organization’s SSO method, they will be required to enable MFA and enroll in one or more of the available MFA methods.\n\nThe MFA rollout will occur in stages to ensure a smooth and consistent adoption across all customers. More details on GitLab’s MFA by Default rollout will be shared in the near future.\n\n### Default passwords\n\n***Goal: Within one year of signing the pledge, demonstrate measurable progress towards reducing default passwords across the manufacturers’ products.***\n\nTo reduce the use of default passwords, GitLab uses randomly generated root passwords for its multiple installation methods. GitLab’s multi-method [installation instructions](https://docs.gitlab.com/ee/install/install_methods.html) also include guidance on how to change the randomly generated root password for each installation.\n\nFor some install methods, such as installing GitLab in a Docker container, the password file with the initial root password is deleted in the first container restart after 24 hours to help further harden the GitLab instance.\n\n### Reducing entire classes of vulnerabilities\n\n***Goal: Within one year of signing the pledge, demonstrate actions taken towards enabling a significant measurable reduction in the prevalence of one or more vulnerability classes across the manufacturer’s products.***\n\nGitLab has published [secure coding guidelines](https://docs.gitlab.com/ee/development/secure_coding_guidelines.html#sast-coverage) to its documentation site that contains descriptions and guidelines for addressing security vulnerabilities commonly identified in the GitLab codebase. \n\nThe guidelines are “intended to help developers identify potential security vulnerabilities early, with the goal of reducing the number of vulnerabilities released over time.” \n\nGitLab continues to improve its [SAST rule coverage](https://docs.gitlab.com/development/secure_coding_guidelines#sast-coverage) to address broader sets of security vulnerabilities for itself and its customers.\n\n### Security patches\n\n***Goal: Within one year of signing the pledge, demonstrate actions taken to measurably increase the installation of security patches by customers.***\n\nGitLab handles all updates related to its GitLab.com and GitLab Dedicated service offerings. Additionally, GitLab publishes a [maintenance policy](https://docs.gitlab.com/ee/policy/maintenance.html), which outlines its approach to releasing updates, backporting, upgrade recommendations and supporting documentation, etc.\n\nGitLab’s documentation has comprehensive guidance on [how to upgrade](https://docs.gitlab.com/ee/update/?tab=Self-compiled+%28source%29#upgrade-based-on-installation-method) self-managed instances based on their deployment model. This includes Omnibus, Helm chart, Docker and self-compiled GitLab installations.\n\nGitLab also provides a detailed [upgrade plan](https://docs.gitlab.com/ee/update/plan_your_upgrade.html) to ensure proper testing and troubleshooting can be performed as well as rollback plans if necessary.\n\nDepending on the version upgrade, specific changes ([example for GitLab 17](https://docs.gitlab.com/ee/update/versions/gitlab_17_changes.html)) for each version are highlighted to ensure a smooth upgrade process and limit unavailability of services.\n\n### Vulnerability disclosure policy\n\n***Goal: Within one year of signing the pledge, publish a vulnerability disclosure policy (VDP).***\n\nGitLab maintains a strong bug bounty program through [HackerOne](https://hackerone.com/gitlab?type=team), a [security.txt](https://gitlab.com/.well-known/security.txt) file highlighting GitLab’s preferred and additional disclosure processes, and [release posts](https://about.gitlab.com/releases/categories/releases/) highlighting security fixes.\n\nCustomers and the general public can subscribe to receive GitLab’s release posts directly in their email inbox.\n\n### Common vulnerability enumerations \n\n***Goal: Within one year of signing the pledge, demonstrate transparency in vulnerability reporting***\n\nGitLab includes the Common Weakness Enumeration (CWE) field in all Common vulnerability enumerations (CVE) records it publishes. Over the past year, GitLab has iterated to also include the Common Platform Enumeration (CPE) field in CVE records.\n\nThe GitLab [CVE assignments project](https://gitlab.com/gitlab-org/cves) stores a copy of all CVE identifiers assigned and published by GitLab in its role as a CVE Numbering Authority.\n\n> Check out [GitLab’s CVE submission template](https://gitlab.com/gitlab-org/cves/-/blob/master/.gitlab/issue_templates/Internal%20GitLab%20Submission.md?ref_type=heads).\n\n### Evidence of intrusions\n\n***Goal: Within one year of signing the pledge, demonstrate a measurable increase in the ability for customers to gather evidence of cybersecurity intrusions affecting the manufacturer’s products.***\n\nGitLab has published an [incident response guide](https://docs.gitlab.com/ee/security/responding_to_security_incidents.html) to help customers respond to incidents involving GitLab instances. Additionally, GitLab has open sourced versions of its [GUARD detection-as-code](https://about.gitlab.com/blog/unveiling-the-guard-framework-to-automate-security-detections-at-gitlab/) and TLDR threat detection frameworks. The repositories for those open source frameworks can be found on [GitLab’s Open Source Security Center](https://about.gitlab.com/security/open-source-resources/).\n\nIn a similar manner, GitLab is adding functionality to its [GitLab.com](http://gitLab.com) service offering to [detect compromised passwords](https://about.gitlab.com/blog/introducing-compromised-password-detection-for-gitlab-com/) for all logins using GitLab’s native username and password authentication method.\n\n## What's next\n\n[GitLab’s Security Division’s mission](https://gitlab.com/gitlab-com/gl-security) is to enable everyone to innovate and succeed on a safe, secure, and trusted DevSecOps platform.\n\nGitLab's security enhancements over the past year have allowed us to demonstrate our commitment to CISA’s Secure by Design Pledge, and they have strengthened our platform and given customers a more reliable and secure foundation to build on. \n\nOur commitment to iteration means we're already focused on the next set of innovations that will drive us forward.\n\n> To learn more about GitLab’s security enhancements, bookmark our [security page on the GitLab Blog](https://about.gitlab.com/blog/categories/security/).\n\n## Read more  \n- [Secure by Design principles meet DevSecOps innovation in GitLab 17](https://about.gitlab.com/blog/secure-by-design-principles-meet-devsecops-innovation-in-gitlab-17/)\n- [Happy birthday, Secure by Design!](https://about.gitlab.com/blog/happy-birthday-secure-by-design/)\n- [Strengthen your cybersecurity strategy with Secure by Design](https://about.gitlab.com/the-source/security/strengthen-your-cybersecurity-strategy-with-secure-by-design/)",[9,496,694,186],{"slug":2734,"featured":91,"template":698},"last-year-we-signed-the-secure-by-design-pledge-heres-our-progress","content:en-us:blog:last-year-we-signed-the-secure-by-design-pledge-heres-our-progress.yml","Last Year We Signed The Secure By Design Pledge Heres Our Progress","en-us/blog/last-year-we-signed-the-secure-by-design-pledge-heres-our-progress.yml","en-us/blog/last-year-we-signed-the-secure-by-design-pledge-heres-our-progress",{"_path":2740,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2741,"content":2747,"config":2752,"_id":2754,"_type":14,"title":2755,"_source":16,"_file":2756,"_stem":2757,"_extension":19},"/en-us/blog/learn-advanced-rust-programming-with-a-little-help-from-ai-code-suggestions",{"title":2742,"description":2743,"ogTitle":2742,"ogDescription":2743,"noIndex":6,"ogImage":2744,"ogUrl":2745,"ogSiteName":686,"ogType":687,"canonicalUrls":2745,"schema":2746},"Learn advanced Rust programming with a little help from AI","Use this guided tutorial, along with AI-powered GitLab Duo Code Suggestions, to continue learning advanced Rust programming.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662439/Blog/Hero%20Images/codewithheart.png","https://about.gitlab.com/blog/learn-advanced-rust-programming-with-a-little-help-from-ai-code-suggestions","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Learn advanced Rust programming with a little help from AI\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Michael Friedrich\"}],\n        \"datePublished\": \"2023-10-12\",\n      }",{"title":2742,"description":2743,"authors":2748,"heroImage":2744,"date":2749,"body":2750,"category":781,"tags":2751},[1318],"2023-10-12","When I started learning a new programming language more than 20 years ago,\nwe had access to the Visual Studio 6 MSDN library, installed from 6 CD-ROMs.\nAlgorithms with pen and paper, design pattern books, and MSDN queries to\nfigure out the correct type were often time-consuming. Learning a new\nprogramming language changed fundamentally in the era of remote\ncollaboration and artificial intelligence (AI). Now you can spin up a\n[remote development\nworkspace](https://about.gitlab.com/blog/quick-start-guide-for-gitlab-workspaces/),\nshare your screen, and engage in a group programming session. With the help\nof [GitLab Duo Code Suggestions](/gitlab-duo/), you always have an\nintelligent partner at your fingertips. Code Suggestions can learn from your\nprogramming style and experience. They only need input and context to\nprovide you with the most efficient suggestions.\n\n\nIn this tutorial, we build on the [getting started blog\npost](/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started/)\nand design and create a simple feed reader application.\n\n\n- [Preparations](#preparations)\n    - [Code Suggestions](#code-suggestions)\n- [Continue learning Rust](#continue-learning-rust)\n    - [Hello, Reader App](#hello-reader-app)\n    - [Initialize project](#initialize-project)\n    - [Define RSS feed URLs](#define-rss-feed-urls)\n- [Modules](#modules)\n    - [Call the module function in main()](#call-the-module-function-in-main)\n- [Crates](#crates)\n    - [feed-rs: parse XML feed](#feed-rs-parse-xml-feed)\n- [Runtime configuration: Program\narguments](#runtime-configuration-program-arguments)\n    - [User input error handling](#user-input-error-handling)\n- [Persistence and data storage](#persistence-and-data-storage)\n\n- [Optimization](#optimization)\n    - [Asynchronous execution](#asynchronous-execution)\n    - [Spawning threads](#spawning-threads)\n    - [Function scopes, threads, and closures](#function-scopes-threads-and-closures)\n- [Parse feed XML into objects](#parse-feed-xml-into-object-types)\n    - [Map generic feed data types](#map-generic-feed-data-types)\n    - [Error handling with Option::unwrap()](#error-handling-with-option-unwrap)\n- [Benchmarks](#benchmarks)\n    - [Sequential vs. Parallel execution benchmark](#sequential-vs-parallel-execution-benchmark)\n    - [CI/CD with Rust caching](#cicd-with-rust-caching)\n- [What is next](#what-is-next)\n    - [Async learning exercises](#async-learning-exercises)\n    - [Share your feedback](#share-your-feedback)\n\n## Preparations\n\nBefore diving into the source code, make sure to set up [VS\nCode](/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started/#vs-code)\nand [your development environment with\nRust](/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started/#development-environment-for-rust).\n\n\n### Code Suggestions\n\nFamiliarize yourself with suggestions before actually verifying the\nsuggestions. GitLab Duo Code Suggestions are provided as you type, so you do\nnot need use specific keyboard shortcuts. To accept a code suggestion, press\nthe `tab` key. Also note that writing new code works more reliably than\nrefactoring existing code. AI is non-deterministic, which means that the\nsame suggestion may not be repeated after deleting the code suggestion.\nWhile Code Suggestions is in Beta, we are working on improving the accuracy\nof generated content overall. Please review the [known\nlimitations](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#known-limitations),\nas this could affect your learning experience.\n\n\n**Tip:** The latest release of Code Suggestions supports multi-line\ninstructions. You can refine the specifications to your needs to get better\nsuggestions.\n\n\n```rust\n    // Create a function that iterates over the source array\n    // and fetches the data using HTTP from the RSS feed items.\n    // Store the results in a new hash map.\n    // Print the hash map to the terminal.\n```\n\n\nThe VS Code extension overlay is shown when offering a suggestion. You can\nuse the `tab` key to accept the suggested line(s), or `cmd cursor right` to\naccept one word. Additionally, the three dots menu allows you to always show\nthe toolbar.\n\n\n![VS Code GitLab Duo Code Suggestions overlay with\ninstructions](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_code_suggestions_options_overlay_keep_toolbar.png){:\n.shadow}\n\n\n## Continue learning Rust\n\nNow, let us continue learning Rust, which is one of the [supported languages\nin Code\nSuggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#supported-languages).\n[Rust by Example](https://doc.rust-lang.org/rust-by-example/) provides an\nexcellent tutorial for beginners, together with the official [Rust\nbook](https://doc.rust-lang.org/book/). Both resources are referenced\nthroughout this blog post.\n\n\n### Hello, Reader App\n\nThere are many ways to create an application and learn Rust. Some of them\ninvolve using existing Rust libraries - so-called `Crates`. We will use them\na bit further into the blog post. For example, you could create a\ncommand-line app that processes images and writes the result to a file.\nSolving a classic maze or writing a Sudoku solver can also be a fun\nchallenge. Game development is another option. The book [Hands-on\nRust](https://hands-on-rust.com/) provides a thorough learning path by\ncreating a dungeon crawler game. My colleague Fatima Sarah Khalid started\nthe [Dragon Realm in C++ with a little help from\nAI](/blog/building-a-text-adventure-using-cplusplus-and-code-suggestions/)\n-- check it out, too.\n\n\nHere is a real use case that helps solve an actual problem: Collecting\nimportant information from different sources into RSS feeds for (security)\nreleases, blog posts, and social discussion forums like Hacker News. Often,\nwe want to filter for specific keywords or versions mentioned in the\nupdates. These requirements allow us to formulate a requirements list for\nour application:\n\n\n1. Fetch data from different sources (HTTP websites, REST API, RSS feeds).\nRSS feeds in the first iteration.\n\n1. Parse the data.\n\n1. Present the data to the user, or write it to disk.\n\n1. Optimize performance.\n\n\nThe following example application output will be available after the\nlearning steps in this blog post:\n\n\n![VS Code Terminal, cargo run with formatted feed entries\noutput](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_terminal_cargo_run_formatted_output_final.png)\n\n\nThe application should be modular and build the foundation to add more data\ntypes, filters, and hooks to trigger actions at a later point.\n\n\n### Initialize project\n\nReminder: `cargo init` in the project root creates the file structure,\nincluding the `main()` entrypoint. Therefore, we will learn how to create\nand use Rust modules in the next step.\n\n\nCreate a new directory called `learn-rust-ai-app-reader`, change into it and\nrun `cargo init`. This command implicitly runs `git init` to initialize a\nnew Git repository locally. The remaining step is to configure the Git\nremote repository path, for example,\n`https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai-app-reader`.\nPlease adjust the path for your namespace. Pushing the Git repository\n[automatically creates a new private project in\nGitLab](https://docs.gitlab.com/ee/user/project/#create-a-new-project-with-git-push).\n\n\n```shell\n\nmkdir learn-rust-ai-app-reader\n\ncd learn-rust-ai-app-reader\n\n\ncargo init\n\n\ngit remote add origin\nhttps://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai-app-reader.git\n\ngit push --set-upstream origin main\n\n```\n\n\nOpen VS Code from the newly created directory. The `code` CLI will spawn a\nnew VS Code window on macOS.\n\n\n```shell\n\ncode .\n\n```\n\n\n### Define RSS feed URLs\n\nAdd a new hashmap to store the RSS feed URLs inside the `src/main.rs` file\nin the `main()` function. You can instruct GitLab Duo Code Suggestions with\na multi-line comment to create a\n[`HashMap`](https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html)\nobject, and initialize it with default values for Hacker News, and\nTechCrunch. Note: Verify that the URLs are correct when you get suggestions.\n\n\n```rust\n\nfn main() {\n    // Define RSS feed URLs in the variable rss_feeds\n    // Use a HashMap\n    // Add Hacker News and TechCrunch\n    // Ensure to use String as type\n\n}\n\n```\n\n\nNote that the code comment provides instructions for:\n\n\n1. The variable name `rss_feeds`.\n\n2. The `HashMap` type.\n\n3. Initial seed key/value pairs.\n\n4. String as type (can be seen with `to_string()` calls).\n\n\nOne possible suggested path can be as follows:\n\n\n```rust\n\nuse std::collections::HashMap;\n\n\nfn main() {\n    // Define RSS feed URLs in the variable rss_feeds\n    // Use a HashMap\n    // Add Hacker News and TechCrunch\n    // Ensure to use String as type\n    let rss_feeds = HashMap::from([\n        (\"Hacker News\".to_string(), \"https://news.ycombinator.com/rss\".to_string()),\n        (\"TechCrunch\".to_string(), \"https://techcrunch.com/feed/\".to_string()),\n    ]);\n\n}\n\n```\n\n\n![VS Code with Code Suggestions for RSS feed URLs for Hacker News and\nTechCrunch](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_main_array_rss_feed_urls_suggested.png)\n\n\nOpen a new terminal in VS Code (cmd shift p - search for `terminal`), and\nrun `cargo build` to build the changes. The error message instructs you to\nadd the `use std::collections::HashMap;` import.\n\n\nThe next step is to do something with the RSS feed URLs. [The previous blog\npost](/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started/)\ntaught us to split code into functions. We want to organize the code more\nmodularly for our reader application, and use Rust modules.\n\n\n## Modules\n\n[Modules](https://doc.rust-lang.org/rust-by-example/mod.html) help with\norganizing code. They can also be used to hide functions into the module\nscope, limiting access to them from the main() scope. In our reader\napplication, we want to fetch the RSS feed content, and parse the XML\nresponse. The `main()` caller should only be able to access the\n`get_feeds()` function, while other functionality is only available in the\nmodule.\n\n\nCreate a new file `feed_reader.rs` in the `src/` directory. Instruct Code\nSuggestions to create a public module named `feed_reader`, and a public\nfunction `get_feeds()` with a String HashMap as input. Important: The file\nand module names need to be the same, following the [Rust module\nstructure](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html).\n\n\n![Code Suggestions: Create public module, with function and input\ntypes](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_rust_public_module_function_input.png){:\n.shadow}\n\n\nInstructing Code Suggestions with the input variable name and type will also\nimport the required `std::collections::HashMap` module. Tip: Experiment with\nthe comments, and refine the variable types to land the best results.\nPassing function parameters as object references is considered best practice\nin Rust, for example.\n\n\n```rust\n\n// Create public module feed_reader\n\n// Define get_feeds() function which takes rss_feeds as String HashMap\nreference as input\n\npub mod feed_reader {\n    use std::collections::HashMap;\n\n    pub fn get_feeds(rss_feeds: &HashMap\u003CString, String>) {\n        // Do something with the RSS feeds\n    }\n}\n\n```\n\n\n![Code Suggestions: Public module with `get_feeds()` function, and suggested\ninput\nvariable](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_rust_public_module_function_input.png){:\n.shadow}\n\n\nInside the function, continue to instruct Code Suggestions with the\nfollowing steps:\n\n\n1. `// Iterate over the RSS feed URLs`\n\n2. `// Fetch URL content`\n\n3. `// Parse XML body`\n\n4. `// Print the result`\n\n\n![Code Suggestions: Public module with `get_feeds()` function, step 1:\nIterate](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_rust_module_function_01_iterate.png){:\n.shadow}\n\n\n![Code Suggestions: Public module with `get_feeds()` function, step 2: Fetch\nURL\ncontent](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_rust_module_function_02_fetch_content.png){:\n.shadow}\n\n\n![Code Suggestions: Public module with `get_feeds()` function, step 3: Parse\nXML\nbody](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_rust_module_function_03_parse_body.png){:\n.shadow}\n\n\n![Code Suggestions: Public module with `get_feeds()` function, step 4: Print\nthe\nresults](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_rust_module_function_04_print_result.png){:\n.shadow}\n\n\nThe following code can be suggested:\n\n\n```rust\n\n// Create public module feed_reader\n\n// Define get_feeds() function which takes rss_feeds as String HashMap\nreference as input\n\npub mod feed_reader {\n    use std::collections::HashMap;\n\n    pub fn get_feeds(rss_feeds: &HashMap\u003CString, String>) {\n        // Iterate over the RSS feed URLs\n        for (name, url) in rss_feeds {\n            println!(\"{}: {}\", name, url);\n\n            // Fetch URL content\n            let body = reqwest::blocking::get(url).unwrap().text().unwrap();\n\n            // Parse XML body\n            let parsed_body = roxmltree::Document::parse(&body).unwrap();\n\n            // Print the result\n            println!(\"{:#?}\", parsed_body);\n        }\n    }\n}\n\n```\n\n\nYou see a new keyword here:\n[`unwrap()`](https://doc.rust-lang.org/rust-by-example/error/option_unwrap.html).\nRust does not support `null` values, and uses the [`Option`\ntype](https://doc.rust-lang.org/rust-by-example/std/option.html) for any\nvalue. If you are certain to use a specific wrapped type, for example,\n`Text` or `String`, you can call the `unwrap()` method to get the value. The\n`unwrap()` method will panic if the value is `None`.\n\n\n**Note** Code Suggestions referred to the `reqwest::blocking::get` function\nfor the `// Fetch URL content` comment instruction. The [`reqwest`\ncrate](https://docs.rs/reqwest/latest/reqwest/) name is intentional and not\na typo. It provides a convenient, higher-level HTTP client for async and\nblocking requests.\n\n\nParsing the XML body is tricky - you might get different results, and the\nschema is not the same for every RSS feed URL. Let us try to call the\n`get_feeds()` function, and then work on improving the code.\n\n\n### Call the module function in main()\n\n\nThe main() function does not know about the `get_feeds()` function yet, so\nwe need to import its module. In other programming languages, you might have\nseen the keywords `include` or `import`. The Rust module system is\ndifferent.\n\n\nModules are organized in path directories. In our example, both source files\nexist on the same directory level. `feed_reader.rs` is interpreted as crate,\ncontaining one module called `feed_reader`, which defines the function\n`get_feeds()`.\n\n\n```\n\nsrc/\n  main.rs\n  feed_reader.rs\n```\n\n\nIn order to access `get_feeds()` from the `feed_reader.rs` file, we need to\n[bring module\npath](https://doc.rust-lang.org/book/ch07-04-bringing-paths-into-scope-with-the-use-keyword.html)\ninto the `main.rs` scope first, and then call the full function path.\n\n\n```rust\n\nmod feed_reader;\n\n\nfn main() {\n\n    feed_reader::feed_reader::get_feeds(&rss_feeds);\n\n```\n\n\nAlternatively, we can import the full function path with the `use` keyword,\nand later use the short function name.\n\n\n```rust\n\nmod feed_reader;\n\nuse feed_reader::feed_reader::get_feeds;\n\n\nfn main() {\n\n    get_feeds(&rss_feeds);\n\n```\n\n\n**Tip:** I highly recommend reading the [Clear explanation of the Rust\nmodule system blog\npost](https://www.sheshbabu.com/posts/rust-module-system/) to get a better\nvisual understanding.\n\n\n```diff\n\n\nfn main() {\n    // ...\n\n    // Print feed_reader get_feeds() output\n    println!(\"{}\", feed_reader::get_feeds(&rss_feeds));\n```\n\n\n```rust\n\nuse std::collections::HashMap;\n\n\nmod feed_reader;\n\n// Alternative: Import full function path\n\n//use feed_reader::feed_reader::get_feeds;\n\n\nfn main() {\n    // Define RSS feed URLs in the variable rss_feeds\n    // Use a HashMap\n    // Add Hacker News and TechCrunch\n    // Ensure to use String as type\n    let rss_feeds = HashMap::from([\n        (\"Hacker News\".to_string(), \"https://news.ycombinator.com/rss\".to_string()),\n        (\"TechCrunch\".to_string(), \"https://techcrunch.com/feed/\".to_string()),\n    ]);\n\n    // Call get_feeds() from feed_reader module\n    feed_reader::feed_reader::get_feeds(&rss_feeds);\n    // Alternative: Imported full path, use short path here.\n    //get_feeds(&rss_feeds);\n}\n\n```\n\n\nRun `cargo build` in the terminal again to build the code.\n\n\n```shell\n\ncargo build\n\n```\n\n\nPotential build errors when Code Suggestions refer to common code and\nlibraries for HTTP requests, and XML parsing:\n\n\n1. Error: `could not find blocking in reqwest`. Solution: Enable the\n`blocking` feature for the crate in `Config.toml`: `reqwest = { version =\n\"0.11.20\", features = [\"blocking\"] }`.\n\n2. Error: `failed to resolve: use of undeclared crate or module reqwest`.\nSolution: Add the `reqwest` crate.\n\n3. Error: `failed to resolve: use of undeclared crate or module roxmltree`.\nSolution: Add the `roxmltree` crate.\n\n\n```shell\n\nvim Config.toml\n\n\nreqwest = { version = \"0.11.20\", features = [\"blocking\"] }\n\n```\n\n\n```shell\n\ncargo add reqwest\n\ncargo add roxmltree\n\n```\n\n\n**Tip:** Copy the error message string, with a leading `Rust \u003Cerror\nmessage>` into your preferred browser to check whether a missing crate is\navailable. Usually this search leads to a result on crates.io and you can\nadd the missing dependencies.\n\n\nWhen the build is successful, run the code with `cargo run` and inspect the\nHacker News RSS feed output.\n\n\n![VS Code terminal, cargo run to fetch Hacker News XML\nfeed](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_terminal_fetch_rss_feed_output_hacker_news.png){:\n.shadow}\n\n\nWhat is next with parsing the XML body into human-readable format? In the\nnext section, we will learn about existing solutions and how Rust crates\ncome into play.\n\n\n## Crates\n\nRSS feeds share a common set of protocols and specifications. It feels like\nreinventing the wheel to parse XML items and understand the lower object\nstructure. Recommendation for these types of tasks: Look whether someone\nelse had the same problem already and might have created code to solve the\nproblem.\n\n\nReusable library code in Rust is organized in so-called\n[`Crates`](https://doc.rust-lang.org/rust-by-example/crates.html), and made\navailable in packages, and the package registry on crates.io. You can add\nthese dependencies to your project by editing the `Config.toml` in the\n`[dependencies]` section, or using `cargo add \u003Cname>`.\n\n\nFor the reader app, we want to use the [feed-rs\ncrate](https://crates.io/crates/feed-rs). Open a new terminal, and run the\nfollowing command:\n\n\n```shell\n\ncargo add feed-rs\n\n```\n\n\n![VS Code Terminal Terminal: Add crate, verify in\nConfig.toml](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_rust_crate_add_feed-rs_explained.png)\n\n\n### feed-rs: parse XML feed\n\nNavigate into `src/feed_reader.rs` and modify the part where we parse the\nXML body. Code Suggestions understands how to call the `feed-rs` crate\n`parser::parse` function -- there is only one specialty here: `feed-rs`\n[expects string input as raw\nbytes](https://docs.rs/feed-rs/latest/feed_rs/parser/fn.parse_with_uri.html)\nto determine the encoding itself. We can provide instructions in the comment\nto get the expected result though.\n\n\n```rust\n            // Parse XML body with feed_rs parser, input in bytes\n            let parsed_body = feed_rs::parser::parse(body.as_bytes()).unwrap();\n```\n\n\n![Code Suggestions: Public module with `get_feeds()` function, step 5:\nModify XML parser to\nfeed-rs](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_rust_module_function_05_use_feed_rs_to_parse.png){:\n.shadow}\n\n\nThe benefit of using `feed-rs` is not immediately visible until you see the\nprinted output with `cargo run`: All keys and values are mapped to their\nrespective Rust object types, and can be used for further operations.\n\n\n![VS Code terminal, cargo run to fetch Hacker News XML\nfeed](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_terminal_fetch_rss_feed_output_hacker_news_feed_rs.png){:\n.shadow}\n\n\n## Runtime configuration: Program arguments\n\nUntil now, we have run the program with hard-coded RSS feed values compiled\ninto the binary. The next step is allowing to configure the RSS feeds at\nruntime.\n\n\nRust provides [program\narguments](https://doc.rust-lang.org/rust-by-example/std_misc/arg.html) in\nthe standard misc library. [Parsing the\narguments](https://doc.rust-lang.org/rust-by-example/std_misc/arg/matching.html)\nprovides a better and faster learning experience than aiming for advanced\nprogram argument parsers (for example, the\n[clap](https://docs.rs/clap/latest/clap/) crate), or moving the program\nparameters into a configuration file and format\n([TOML](https://toml.io/en/), YAML). You are reading these lines after I\ntried and failed with different routes for the best learning experience.\nThis should not stop you from taking the challenge to configure RSS feeds in\nalternative ways.\n\n\nAs a boring solution, the command parameters can be passed as `\"name,url\"`\nstring value pairs, and then are split by the `,` character to extract the\nname and URL values. The comment instructs Code Suggestions to perform these\noperations and extend the `rss_feeds` HashMap with the new values. Note that\nthe variable might not be mutable, and, therefore, needs to be modified to\n`let mut rss_feeds`.\n\n\nNavigate into `src/main.rs` and add the following code to the `main()`\nfunction after the `rss_feeds` variable. Start with a comment to define the\nprogram arguments, and check the suggested code snippets.\n\n\n```rust\n    // Program args, format \"name,url\"\n    // Split value by , into name, url and add to rss_feeds\n```\n\n\n![Code suggestions for program arguments, and splitting name,URL values for\nthe rss_feeds\nvariable](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_rust_program_args_boring_solution.png){:\n.shadow}\n\n\nThe full code example can look like the following:\n\n\n```rust\n\nfn main() {\n    // Define RSS feed URLs in the variable rss_feeds\n    // Use a HashMap\n    // Add Hacker News and TechCrunch\n    // Ensure to use String as type\n    let mut rss_feeds = HashMap::from([\n        (\"Hacker News\".to_string(), \"https://news.ycombinator.com/rss\".to_string()),\n        (\"TechCrunch\".to_string(), \"https://techcrunch.com/feed/\".to_string()),\n    ]);\n\n    // Program args, format \"name,url\"\n    // Split value by , into name, url and add to rss_feeds\n    for arg in std::env::args().skip(1) {\n        let mut split = arg.split(\",\");\n        let name = split.next().unwrap();\n        let url = split.next().unwrap();\n        rss_feeds.insert(name.to_string(), url.to_string());\n    }\n\n    // Call get_feeds() from feed_reader module\n    feed_reader::feed_reader::get_feeds(&rss_feeds);\n    // Alternative: Imported full path, use short path here.\n    //get_feeds(&rss_feeds);\n}\n\n```\n\n\nYou can pass program arguments directly to the `cargo run` command,\npreceding the arguments with `--`. Enclose all arguments with double quotes,\nput the name followed by a comma and the RSS feed URL as argument. Separate\nall arguments with whitespaces.\n\n\n```\n\ncargo build\n\n\ncargo run -- \"GitLab Blog,https://about.gitlab.com/atom.xml\"\n\"CNCF,https://www.cncf.io/feed/\"\n\n```\n\n\n![VS Code terminal, RSS feed output example for the GitLab\nblog](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_terminal_gitlab_blog_rss_feed_example.png){:\n.shadow}\n\n\n### User input error handling\n\nIf the provided user input does not match the program expectation, we need\nto [throw an error](https://doc.rust-lang.org/rust-by-example/error.html)\nand help the caller to fix the program arguments. For example, passing a\nmalformed URL format should be treated as a runtime error. Instruct Code\nSuggestions with a code comment to throw an error if the URL is not valid.\n\n\n```rust\n    // Ensure that URL contains a valid format, otherwise throw an error\n```\n\n\nOne possible solution is to check if the `url` variable starts with\n`http://` or `https://`. If not, throw an error using the [panic!\nmacro](https://doc.rust-lang.org/rust-by-example/std/panic.html). The full\ncode example looks like the following:\n\n\n```rust\n    // Program args, format \"name,url\"\n    // Split value by , into name, url and add to rss_feeds\n    for arg in std::env::args().skip(1) {\n        let mut split = arg.split(\",\");\n        let name = split.next().unwrap();\n        let url = split.next().unwrap();\n\n        // Ensure that URL contains a valid format, otherwise throw an error\n        if !url.starts_with(\"http://\") && !url.starts_with(\"https://\") {\n            panic!(\"Invalid URL format: {}\", url);\n        }\n\n        rss_feeds.insert(name.to_string(), url.to_string());\n    }\n```\n\n\nTest the error handling with removing a `:` in one of the URL strings. Add\nthe `RUST_BACKTRACE=full` environment variable to get more verbose output\nwhen the `panic()` call happens.\n\n\n```\n\nRUST_BACKTRACE=full cargo run -- \"GitLab\nBlog,https://about.gitlab.com/atom.xml\" \"CNCF,https//www.cncf.io/feed/\"\n\n```\n\n\n![VS Code Terminal with wrong URL format, panic error\nbacktrace](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_terminal_url_format_error_panic_backtrace.png){:\n.shadow}\n\n\n## Persistence and data storage\n\nThe boring solution for storing the feed data is to dump the parsed body\ninto a new file. Instruct Code Suggestions to use a pattern that includes\nthe RSS feed name, and the current ISO date.\n\n\n```rust\n    // Parse XML body with feed_rs parser, input in bytes\n    let parsed_body = feed_rs::parser::parse(body.as_bytes()).unwrap();\n\n    // Print the result\n    println!(\"{:#?}\", parsed_body);\n\n    // Dump the parsed body to a file, as name-current-iso-date.xml\n    let now = chrono::offset::Local::now();\n    let filename = format!(\"{}-{}.xml\", name, now.format(\"%Y-%m-%d\"));\n    let mut file = std::fs::File::create(filename).unwrap();\n    file.write_all(body.as_bytes()).unwrap();\n```\n\n\nA possible suggestion will include using the [chrono\ncrate](https://crates.io/crates/chrono). Add it using `cargo add chrono` and\nthen invoke `cargo build` and `cargo run` again.\n\n\nThe files are written into the same directory where `cargo run` was\nexecuted. If you are executing the binary direcly in the `target/debug/`\ndirectory, all files will be dumped there.\n\n\n![VS Code with CNCF RSS feed content file, saved on\ndisk](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_cncf_rss_feed_saved_on_disk.png)\n\n\n## Optimization\n\nThe entries in the `rss_feeds` variable are executed sequentially. Imagine\nhaving a list of 100+ URLs configured - this could take a long time to fetch\nand process. What if we could execute multiple fetch requests in parallel?\n\n\n### Asynchronous execution\n\nRust provides [threads](https://doc.rust-lang.org/book/ch16-01-threads.html)\nfor asynchronous execution.\n\n\nThe simplest solution will be spawning a thread for each RSS feed URL. We\nwill discuss optimization strategies later. Before you continue with\nparallel execution, measure the sequential code execution time by preceding\nthe `time` command with `cargo run`.\n\n\n```\n\ntime cargo run -- \"GitLab Blog,https://about.gitlab.com/atom.xml\"\n\"CNCF,https://www.cncf.io/feed/\"\n\n\n0.21s user 0.08s system 10% cpu 2.898 total\n\n```\n\n\nNote that this exercise could require more manual code work. It is\nrecommended to persist the sequential working state in a new Git commit and\nbranch `sequential-exec`, to better compare the impact of parallel\nexecution.\n\n\n```shell\n\ngit commit -avm \"Sequential execution working\"\n\ngit checkout -b sequential-exec\n\ngit push -u origin sequential-exec\n\n\ngit checkout main\n\n```\n\n\n### Spawning threads\n\nOpen `src/feed_reader.rs` and refactor the `get_feeds()` function. Start\nwith a Git commit for the current state, and then delete the contents of the\nfunction scope. Add the following code comments with instructions for Code\nSuggestions:\n\n\n1. `// Store threads in vector`: Store thread handles in a vector, so we can\nwait for them to finish at the end of the function call.\n\n2. `// Loop over rss_feeds and spawn threads`: Create boilerplate code for\niterating over all RSS feeds, and spawn a new thread.\n\n\nAdd the following `use` statements to work with the `thread` and `time`\nmodules.\n\n\n```rust\n    use std::thread;\n    use std::time::Duration;\n```\n\n\nContinue writing the code, and close the for loop. Code Suggestions will\nautomatically propose adding the thread handle in the `threads` vector\nvariable, and offer to join the threads at the end of the function.\n\n\n```rust\n    pub fn get_feeds(rss_feeds: &HashMap\u003CString, String>) {\n\n        // Store threads in vector\n        let mut threads: Vec\u003Cthread::JoinHandle\u003C()>> = Vec::new();\n\n        // Loop over rss_feeds and spawn threads\n        for (name, url) in rss_feeds {\n            let thread_name = name.clone();\n            let thread_url = url.clone();\n            let thread = thread::spawn(move || {\n\n            });\n            threads.push(thread);\n        }\n\n        // Join threads\n        for thread in threads {\n            thread.join().unwrap();\n        }\n    }\n```\n\n\nAdd the `thread` crate, build and run the code again.\n\n\n```shell\n\ncargo add thread\n\n\ncargo build\n\n\ncargo run -- \"GitLab Blog,https://about.gitlab.com/atom.xml\"\n\"CNCF,https://www.cncf.io/feed/\"\n\n```\n\n\nAt this stage, no data is processed or printed. Before we continue re-adding\nthe functionality, let us learn about the newly introduced keywords here.\n\n\n### Function scopes, threads, and closures\n\nThe suggested code brings new keywords and design patterns to learn. The\nthread handle is of the type `thread::JoinHandle`, indicating that we can\nuse it to wait for the threads to finish\n([join()](https://doc.rust-lang.org/book/ch16-01-threads.html#waiting-for-all-threads-to-finish-using-join-handles)).\n\n\n`thread::spawn()` spawns a new thread, where we can pass a function object.\nIn this case, a\n[closure](https://doc.rust-lang.org/book/ch13-01-closures.html) expression\nis passed as anonymous function. Closure inputs are passed using the `||`\nsyntax. You will recognize the [`move`\nClosure](https://doc.rust-lang.org/book/ch16-01-threads.html#using-move-closures-with-threads),\nwhich moves the function scoped variables into the thread scope. This avoids\nmanually specifying which variables need to be passed into the new\nfunction/closure scope.\n\n\nThere is a limitation though: `rss_feeds` is a reference `&`, passed as\nparameter by the `get_feeds()` function caller. The variable is only valid\nin the function scope. Use the following code snippet to provoke this error:\n\n\n```rust\n\npub fn get_feeds(rss_feeds: &HashMap\u003CString, String>) {\n\n    // Store threads in vector\n    let mut threads: Vec\u003Cthread::JoinHandle\u003C()>> = Vec::new();\n\n    // Loop over rss_feeds and spawn threads\n    for (key, value) in rss_feeds {\n        let thread = thread::spawn(move || {\n            println!(\"{}\", key);\n        });\n    }\n}\n\n```\n\n\n![VS Code Terminal, variable scope error with references and thread move\nclosure](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_terminal_cargo_build_error_function_threads_variable_scopes.png){:\n.shadow}\n\n\nAlthough the `key` variable was created in the function scope, it references\nthe `rss_feeds` variable, and therefore, it cannot be moved into the thread\nscope. Any values accessed from the function parameter `rss_feeds` hash map\nwill require a local copy with `clone()`.\n\n\n![VS Code Terminal, thread spawn with\nclone](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_rust_thread_spawn_clone.png){:\n.shadow}\n\n\n```rust\n\npub fn get_feeds(rss_feeds: &HashMap\u003CString, String>) {\n\n    // Store threads in vector\n    let mut threads: Vec\u003Cthread::JoinHandle\u003C()>> = Vec::new();\n\n    // Loop over rss_feeds and spawn threads\n    for (name, url) in rss_feeds {\n        let thread_name = name.clone();\n        let thread_url = url.clone();\n        let thread = thread::spawn(move || {\n            // Use thread_name and thread_url as values, see next chapter for instructions.\n```\n\n\n## Parse feed XML into object types\n\nThe next step is to repeat the RSS feed parsing steps in the thread closure.\nAdd the following code comments with instructions for Code Suggestions:\n\n\n1. `// Parse XML body with feed_rs parser, input in bytes` to tell Code\nSuggestions that we want to fetch the RSS feed URL content, and parse it\nwith the `feed_rs` crate functions.\n\n2. `// Check feed_type attribute feed_rs::model::FeedType::RSS2 or Atom and\nprint its name`: Extract the feed type by comparing the `feed_type`\nattribute with the\n[`feed_rs::model::FeedType`](https://docs.rs/feed-rs/latest/feed_rs/model/enum.FeedType.html).\nThis needs more direct instructions for Code Suggestions telling it about\nthe exact Enum values to match against.\n\n\n![Instruct Code Suggestions to match against specific feed\ntypes](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_feed_rs_type_condition.png){:\n.shadow}\n\n\n```rust\n            // Parse XML body with feed_rs parser, input in bytes\n            let body = reqwest::blocking::get(thread_url).unwrap().bytes().unwrap();\n            let feed = feed_rs::parser::parse(body.as_ref()).unwrap();\n\n            // Check feed_type attribute feed_rs::model::FeedType::RSS2 or Atom and print its name\n            if feed.feed_type == feed_rs::model::FeedType::RSS2 {\n                println!(\"{} is an RSS2 feed\", thread_name);\n            } else if feed.feed_type == feed_rs::model::FeedType::Atom {\n                println!(\"{} is an Atom feed\", thread_name);\n            }\n```\n\n\nBuild and run the program again, and verify its output.\n\n\n```\n\ntime cargo run -- \"GitLab Blog,https://about.gitlab.com/atom.xml\"\n\"CNCF,https://www.cncf.io/feed/\"\n\n\nCNCF is an RSS2 feed\n\nTechCrunch is an RSS2 feed\n\nGitLab Blog is an Atom feed\n\nHacker News is an RSS2 feed\n\n```\n\n\nLet us verify this output by opening the feed URLs in the browser, or\ninspecting the previously downloaded files.\n\n\nHacker News supports RSS version 2.0, with\n`channel(title,link,description,item(title,link,pubDate,comments))`.\nTechCrunch and the CNCF blog follow a similar structure.\n\n```xml\n\n\u003Crss version=\"2.0\">\u003Cchannel>\u003Ctitle>Hacker\nNews\u003C/title>\u003Clink>https://news.ycombinator.com/\u003C/link>\u003Cdescription>Links for\nthe intellectually curious, ranked by\nreaders.\u003C/description>\u003Citem>\u003Ctitle>Writing a debugger from scratch:\nBreakpoints\u003C/title>\u003Clink>https://www.timdbg.com/posts/writing-a-debugger-from-scratch-part-5/\u003C/link>\u003CpubDate>Wed,\n27 Sep 2023 06:31:25\n+0000\u003C/pubDate>\u003Ccomments>https://news.ycombinator.com/item?id=37670938\u003C/comments>\u003Cdescription>\u003C![CDATA[\u003Ca\nhref=\"https://news.ycombinator.com/item?id=37670938\">Comments\u003C/a>]]>\u003C/description>\u003C/item>\u003Citem>\n\n```\n\n\nThe GitLab blog uses the\n[Atom](https://datatracker.ietf.org/doc/html/rfc4287) feed format similar to\nRSS, but still requires different parsing logic.\n\n```xml\n\n\u003C?xml version='1.0' encoding='utf-8' ?>\n\n\u003Cfeed xmlns='http://www.w3.org/2005/Atom'>\n\n\u003C!-- / Get release posts -->\n\n\u003C!-- / Get blog posts -->\n\n\u003Ctitle>GitLab\u003C/title>\n\n\u003Cid>https://about.gitlab.com/blog\u003C/id>\n\n\u003Clink href='https://about.gitlab.com/blog/' />\n\n\u003Cupdated>2023-09-26T00:00:00+00:00\u003C/updated>\n\n\u003Cauthor>\n\n\u003Cname>The GitLab Team\u003C/name>\n\n\u003C/author>\n\n\u003Centry>\n\n\u003Ctitle>Atlassian Server ending: Goodbye disjointed toolchain, hello\nDevSecOps platform\u003C/title>\n\n\u003Clink\nhref='https://about.gitlab.com/blog/atlassian-server-ending-move-to-a-single-devsecops-platform/'\nrel='alternate' />\n\n\u003Cid>https://about.gitlab.com/blog/atlassian-server-ending-move-to-a-single-devsecops-platform/\u003C/id>\n\n\u003Cpublished>2023-09-26T00:00:00+00:00\u003C/published>\n\n\u003Cupdated>2023-09-26T00:00:00+00:00\u003C/updated>\n\n\u003Cauthor>\n\n\u003Cname>Dave Steer, Justin Farris\u003C/name>\n\n\u003C/author>\n\n```\n\n\n### Map generic feed data types\n\nUsing\n[`roxmltree::Document::parse`](https://docs.rs/roxmltree/latest/roxmltree/struct.Document.html)\nwould require us to understand the XML node tree and its specific tag names.\nFortunately,\n[feed_rs::model::Feed](https://docs.rs/feed-rs/latest/feed_rs/model/struct.Feed.html)\nprovides a combined model for RSS and Atom feeds, therefore let us continue\nusing the `feed_rs` crate.\n\n\n1. Atom: Feed->Feed, Entry->Entry\n\n2. RSS: Channel->Feed, Item->Entry\n\n\nIn addition to the mapping above, we need to extract the required\nattributes, and map their data types. It is helpful to open the\n[feed_rs::model\ndocumentation](https://docs.rs/feed-rs/latest/feed_rs/model/index.html) to\nunderstand the structs and their fields and implementations. Otherwise, some\nsuggestions would result in type conversion errors and compilation failures,\nthat are specific to the `feed_rs` implementation.\n\n\nA [`Feed`](https://docs.rs/feed-rs/latest/feed_rs/model/struct.Feed.html)\nstruct provides the `title`, type `Option\u003CText>` (either a value is set, or\nnothing). An\n[`Entry`](https://docs.rs/feed-rs/latest/feed_rs/model/struct.Entry.html)\nstruct provides:\n\n\n1. `title`: `Option\u003CText>`with\n[`Text`](https://docs.rs/feed-rs/latest/feed_rs/model/struct.Text.html) and\nthe `content` field as `String`.\n\n2. `updated`: `Option\u003CDateTime\u003CUtc>>` with\n[`DateTime`](https://docs.rs/chrono/latest/chrono/struct.DateTime.html) with\nthe [`format()`\nmethod](https://docs.rs/chrono/latest/chrono/struct.DateTime.html#method.format).\n\n3. `summary`: `Option\u003CText>`\n[`Text`](https://docs.rs/feed-rs/latest/feed_rs/model/struct.Text.html) and\nthe `content` field as `String`.\n\n4. `links`: `Vec\u003CLink>`, vector with\n[`Link`](https://docs.rs/feed-rs/latest/feed_rs/model/struct.Link.html)\nitems. The `href` attribute provides the raw URL string.\n\n\nUse this knowledge to extract the required data from the feed entries.\nReminder that all `Option` types need to call `unwrap()`, which requires\nmore raw instructions for Code Suggestions.\n\n\n```rust\n                // https://docs.rs/feed-rs/latest/feed_rs/model/struct.Feed.html\n                // https://docs.rs/feed-rs/latest/feed_rs/model/struct.Entry.html\n                // Loop over all entries, and print\n                // title.unwrap().content\n                // published.unwrap().format\n                // summary.unwrap().content\n                // links href as joined string\n                for entry in feed.entries {\n                    println!(\"Title: {}\", entry.title.unwrap().content);\n                    println!(\"Published: {}\", entry.published.unwrap().format(\"%Y-%m-%d %H:%M:%S\"));\n                    println!(\"Summary: {}\", entry.summary.unwrap().content);\n                    println!(\"Links: {:?}\", entry.links.iter().map(|link| link.href.clone()).collect::\u003CVec\u003CString>>().join(\", \"));\n                    println!();\n                }\n```\n\n\n![Code suggestions to print feed entry types, with specific\nrequirements](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_print_feed_entries_fields_with_rust_type_specifics.png){:\n.shadow}\n\n\n### Error handling with Option unwrap()\n\nContinue iterating on the multi-line instructions after building and running\nthe program again. Spoiler: `unwrap()` will call the `panic!` macro and\ncrash the program when it encounters empty values. This can happen if a\nfield like `summary` is not set in the feed data.\n\n\n```shell\n\nGitLab Blog is an Atom feed\n\nTitle: How the Colmena project uses GitLab to support citizen journalists\n\nPublished: 2023-09-27 00:00:00\n\nthread '\u003Cunnamed>' panicked at 'called `Option::unwrap()` on a `None`\nvalue', src/feed_reader.rs:40:59\n\n```\n\n\nA potential solution is to use\n[`std::Option::unwrap_or_else`](https://doc.rust-lang.org/std/option/enum.Option.html#method.unwrap_or_else)\nand set an empty string as default value. The syntax requires a closure that\nreturns an empty `Text` struct instantiation.\n\n\nSolving the problem required many attempts to find the correct\ninitialization, passing just an empty string did not work with the custom\ntypes. I will show you all my endeavors, including the research paths.\n\n\n```rust\n\n// Problem: The `summary` attribute is not always initialized. unwrap() will\npanic! then.\n\n// Requires use mime; and use feed_rs::model::Text;\n\n/*\n\n// 1st attempt: Use unwrap() to extraxt Text from Option\u003CText> type.\n\nprintln!(\"Summary: {}\", entry.summary.unwrap().content);\n\n// 2nd attempt. Learned about unwrap_or_else, passing an empty string.\n\nprintln!(\"Summary: {}\", entry.summary.unwrap_or_else(|| \"\").content);\n\n// 3rd attempt. summary is of the Text type, pass a new struct\ninstantiation.\n\nprintln!(\"Summary: {}\", entry.summary.unwrap_or_else(|| Text{}).content);\n\n// 4th attempt. Struct instantiation requires 3 field values.\n\nprintln!(\"Summary: {}\", entry.summary.unwrap_or_else(|| Text{\"\", \"\",\n\"\"}).content);\n\n// 5th attempt. Struct instantation with public fields requires key: value\nsyntax\n\nprintln!(\"Summary: {}\", entry.summary.unwrap_or_else(|| Text{content_type:\n\"\", src: \"\", content: \"\"}).content);\n\n// 6th attempt. Reviewed expected Text types in\nhttps://docs.rs/feed-rs/latest/feed_rs/model/struct.Text.html and created\nMime and String objects\n\nprintln!(\"Summary: {}\", entry.summary.unwrap_or_else(|| Text{content_type:\nmime::TEXT_PLAIN, src: String::new(), content: String::new()}).content);\n\n// 7th attempt: String and Option\u003CString> cannot be casted automagically.\nCompiler suggested using `Option::Some()`.\n\nprintln!(\"Summary: {}\", entry.summary.unwrap_or_else(|| Text{content_type:\nmime::TEXT_PLAIN, src: Option::Some(), content: String::new()}).content);\n\n*/\n\n\n// xth attempt: Solution. Option::Some() requires a new String object.\n\nprintln!(\"Summary: {}\", entry.summary.unwrap_or_else(|| Text{content_type:\nmime::TEXT_PLAIN, src: Option::Some(String::new()), content:\nString::new()}).content);\n\n```\n\n\nThis approach did not feel satisfying, since the code line is complicated to\nread, and required manual work without help from Code Suggestions. Taking a\nstep back, I reviewed what brought me there - if `Option` is `none`,\n`unwrap()` will throw an error. Maybe there is an easier way to handle this?\nI asked Code Suggestions in a new comment:\n\n\n```\n                // xth attempt: Solution. Option::Some() requires a new String object.\n                println!(\"Summary: {}\", entry.summary.unwrap_or_else(|| Text{content_type: mime::TEXT_PLAIN, src: Option::Some(String::new()), content: String::new()}).content);\n\n                // Alternatively, use Option.is_none()\n```\n\n\n![Code suggestions asked for alternative with\nOptions.is_none](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/code_suggestions_after_complex_unwrap_or_else_ask_for_alternative_option.png){:\n.shadow}\n\n\nIncreased readability, less CPU cycles wasted on `unwrap()`, and a great\nlearning curve from solving a complex problem to using a boring solution.\nWin-win.\n\n\nBefore we forget: Re-add storing the XML data on disk to complete the reader\napp again.\n\n\n```rust\n                // Dump the parsed body to a file, as name-current-iso-date.xml\n                let file_name = format!(\"{}-{}.xml\", thread_name, chrono::Local::now().format(\"%Y-%m-%d-%H-%M-%S\"));\n                let mut file = std::fs::File::create(file_name).unwrap();\n                file.write_all(body.as_ref()).unwrap();\n```\n\n\nBuild and run the program to verify the output.\n\n\n```shell\n\ncargo build\n\n\ntime cargo run -- \"GitLab Blog,https://about.gitlab.com/atom.xml\"\n\"CNCF,https://www.cncf.io/feed/\"\n\n```\n\n\n![VS Code Terminal, cargo run with formatted feed entries\noutput](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/vs_code_terminal_cargo_run_formatted_output_final.png)\n\n\n## Benchmarks\n\n\n### Sequential vs. Parallel execution benchmark\n\nCompare the execution time benchmarks by creating five samples each.\n\n\n1. Sequential execution. [Example source code\nMR](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai-app-reader/-/merge_requests/1)\n\n2. Parallel exeuction. [Example source code\nMR](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai-app-reader/-/merge_requests/3)\n\n\n```shell\n\n# Sequential\n\ngit checkout sequential-exec\n\n\ntime cargo run -- \"GitLab Blog,https://about.gitlab.com/atom.xml\"\n\"CNCF,https://www.cncf.io/feed/\"\n\n\n0.21s user 0.08s system 10% cpu 2.898 total\n\n0.21s user 0.08s system 11% cpu 2.585 total\n\n0.21s user 0.09s system 10% cpu 2.946 total\n\n0.19s user 0.08s system 10% cpu 2.714 total\n\n0.20s user 0.10s system 10% cpu 2.808 total\n\n```\n\n\n```shell\n\n# Parallel\n\ngit checkout parallel-exec\n\n\ntime cargo run -- \"GitLab Blog,https://about.gitlab.com/atom.xml\"\n\"CNCF,https://www.cncf.io/feed/\"\n\n\n0.19s user 0.08s system 17% cpu 1.515 total\n\n0.18s user 0.08s system 16% cpu 1.561 total\n\n0.18s user 0.07s system 17% cpu 1.414 total\n\n0.19s user 0.08s system 18% cpu 1.447 total\n\n0.17s user 0.08s system 16% cpu 1.453 total\n\n```\n\n\nThe CPU usage increased for parallel execution of four RSS feed threads, but\nit nearly halved the total time compared to sequential execution. With that\nin mind, we can continue learning Rust and optimize the code and\nfunctionality.\n\n\nNote that we are running the debug build through Cargo, and not the\noptimized released builds yet. There are caveats with parallel execution\nthough: Some HTTP endpoints put rate limits in place, where parallelism\ncould hit these thresholds easier.\n\n\nThe system executing multiple threads in parallel might get overloaded too –\nthreads require context switching in the Kernel, assigning resources to each\nthread. While one thread gets computing resources, other threads are put to\nsleep. If there are too many threads spawned, this might slow down the\nsystem, rather than speeding up the operations. Solutions include design\npatterns such as [work\nqueues](https://docs.rs/work-queue/latest/work_queue/), where the caller\nadds a task into a queue, and a defined number of worker threads pick up the\ntasks for asynchronous execution.\n\n\nRust also provides data synchronisation between threads, so-called\n[channels](https://doc.rust-lang.org/rust-by-example/std_misc/channels.html).\nTo ensure concurrent data access,\n[mutexes](https://doc.rust-lang.org/std/sync/struct.Mutex.html) are\navailable to provide safe locks.\n\n\n### CI/CD with Rust caching\n\nAdd the following CI/CD configuration into the `.gitlab-ci.yml` file. The\n`run-latest` job calls `cargo run` with RSS feed URL examples, and measures\nthe execution time continuously.\n\n\n```\n\nstages:\n  - build\n  - test\n  - run\n\ndefault:\n  image: rust:latest\n  cache:\n    key: ${CI_COMMIT_REF_SLUG}\n    paths:\n      - .cargo/bin\n      - .cargo/registry/index\n      - .cargo/registry/cache\n      - target/debug/deps\n      - target/debug/build\n    policy: pull-push\n\n# Cargo data needs to be in the project directory for being cached.\n\nvariables:\n  CARGO_HOME: ${CI_PROJECT_DIR}/.cargo\n\nbuild-latest:\n  stage: build\n  script:\n    - cargo build --verbose\n\ntest-latest:\n  stage: build\n  script:\n    - cargo test --verbose\n\nrun-latest:\n  stage: run\n  script:\n    - time cargo run -- \"GitLab Blog,https://about.gitlab.com/atom.xml\" \"CNCF,https://www.cncf.io/feed/\"\n```\n\n\n![GitLab CI/CD pipelines for Rust, cargo run\noutput](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-advanced-programming/gitlab_cicd_pipeline_rust_cargo_run_output.png){:\n.shadow}\n\n\n## What is next\n\nThis blog post was challenging to create, with both learning advanced Rust\nprogramming techniques myself, and finding a good learning curve with Code\nSuggestions. The latter greatly helps with quickly generating code, not just\nboilerplate snippets – it understands the local context, and better\nunderstands the purpose and scope of the algorithm, the more code you write.\nAfter reading this blog post, you know of a few challenges and turnarounds.\nThe example solution code for the reader app is available in [the\nlearn-rust-ai-app-reader\nproject](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai-app-reader).\n\n\nParsing RSS feeds is challenging since it involves data structures, with\nexternal HTTP requests and parallel optimizations. As an experienced Rust\nuser, you might have wondered: `Why not use the std::rss crate?` -- It is\noptimized for advanced asynchronous execution, and does not allow to show\nand explain the different Rust functionalities, explained in this blog post.\nAs an async exercise, try to rewrite the code using the [`rss`\ncrate](https://docs.rs/rss/latest/rss/).\n\n\n### Async learning exercises\n\nThe lessons learned in this blog post also lay the foundation for future\nexploration with persistent storage and presenting the data. Here are a few\nideas where you can continue learning Rust and optimize the reader app:\n\n\n1. Data storage: Use a database like sqlite, and RSS feed update tracking.\n\n2. Notifications: Spawn child processes to trigger notifications into\nTelegram, etc.\n\n3. Functionality: Extend the reader types to REST APIs\n\n4. Configuration: Add support for configuration files for RSS feeds, APIs,\netc.\n\n5. Efficiency: Add support for filters, and subscribed tags.\n\n6. Deployments: Use a webserver, collect Prometheus metrics, and deploy to\nKubernetes.\n\n\nIn a future blog post, we will discuss some of these ideas, and how to\nimplement them. Dive into existing RSS feed implementations, and learn how\nyou can refactor the existing code into leveraging more Rust libraries\n(`crates`).\n\n\n### Share your feedback\n\nWhen you use [GitLab Duo](/gitlab-duo/) Code Suggestions, please [share your\nthoughts in the feedback\nissue](https://gitlab.com/gitlab-org/gitlab/-/issues/405152).\n",[9,761,827,1016,717],{"slug":2753,"featured":6,"template":698},"learn-advanced-rust-programming-with-a-little-help-from-ai-code-suggestions","content:en-us:blog:learn-advanced-rust-programming-with-a-little-help-from-ai-code-suggestions.yml","Learn Advanced Rust Programming With A Little Help From Ai Code Suggestions","en-us/blog/learn-advanced-rust-programming-with-a-little-help-from-ai-code-suggestions.yml","en-us/blog/learn-advanced-rust-programming-with-a-little-help-from-ai-code-suggestions",{"_path":2759,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2760,"content":2766,"config":2771,"_id":2773,"_type":14,"title":2774,"_source":16,"_file":2775,"_stem":2776,"_extension":19},"/en-us/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started",{"title":2761,"description":2762,"ogTitle":2761,"ogDescription":2762,"noIndex":6,"ogImage":2763,"ogUrl":2764,"ogSiteName":686,"ogType":687,"canonicalUrls":2764,"schema":2765},"Learning Rust with a little help from AI","Use this guided tutorial, along with GitLab Duo Code Suggestions, to learn a new programming language.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663918/Blog/Hero%20Images/aipower.jpg","https://about.gitlab.com/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Learning Rust with a little help from AI\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Michael Friedrich\"}],\n        \"datePublished\": \"2023-08-10\",\n      }",{"title":2761,"description":2762,"authors":2767,"heroImage":2763,"date":2768,"body":2769,"category":781,"tags":2770},[1318],"2023-08-10","Learning a new programming language can help broaden your software\ndevelopment expertise, open career opportunities, or create fun challenges.\nHowever, it can be difficult to decide on one specific approach to learning\na new language. Artificial intelligence (AI) can help. In this tutorial,\nyou'll learn how to leverage AI-powered GitLab Duo Code Suggestions for a\nguided experience in learning the Rust programming language.\n\n\n- [Preparations](#preparations)\n  - [VS Code](#vs-code)\n  - [Code Suggestions](#code-suggestions)\n- [Learning a new programming language:\nRust](#learning-a-new-programming-language-rust)\n    - [Development environment for Rust](#development-environment-for-rust)\n    - [Hello, World](#hello-world)\n- [Cargo: Bringing structure into Rust](#cargo-bringing-structure-into-rust)\n\n- [Automation: Configure CI/CD pipeline for\nRust](#automation-configure-cicd-pipeline-for-rust)\n\n- [Continue learning Rust](#continue-learning-rust)\n    - [Define variables and print them](#define-variables-and-print-them)\n    - [Explore variable types](#explore-variable-types)\n    - [Flow control: Conditions and loops](#flow-control-conditions-and-loops)\n    - [Functions](#functions)\n    - [Testing](#testing)\n- [What is next](#what-is-next)\n    - [Async learning exercises](#async-learning-exercises)\n    - [Share your feedback](#share-your-feedback)\n\n## Preparations \n\nChoose your [preferred and supported\nIDE](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-in-other-ides-and-editors),\nand follow the documentation to enable code suggestions for [GitLab.com\nSaaS](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-on-gitlab-saas)\nor [GitLab self-managed\ninstances](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-on-self-managed-gitlab).\n\n\nProgramming languages can require an install of the language interpreter\ncommand-line tools or compilers that generate binaries from source code to\nbuild and run the application.\n\n\nTip: You can also use [GitLab Remote Development\nworkspaces](/blog/quick-start-guide-for-gitlab-workspaces/) to\ncreate your own cloud development environments, instead of local development\nenvironments. This blog post focuses on using VS Code and the GitLab Web\nIDE. \n\n\n### VS Code\n\nOn macOS, you can [install VS Code](https://code.visualstudio.com/download)\nas a Homebrew cask or manually download and install it. \n\n\n```shell\n\nbrew install --cask visual-studio-code \n\n```\n\n\nNavigate to the `Extensions` menu and search for `gitlab workflow`. Install\nthe [GitLab workflow extension for VS\nCode](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow). \n\n\nTip: VS Code will also detect the programming languages, and offer to\ninstall additional plugins for syntax highlighting and development\nexperience. \n\n\n### Code Suggestions\n\nIt can help to familiarize yourself with suggestions before actually\nverifying the suggestions. GitLab Code Suggestions are provided as you type,\nso you do not need use specific keyboard shortcuts. To accept a code\nsuggestion, press the `tab` key. Also note that writing new code works more\nreliably than refactoring existing code. AI is non-deterministic, which\nmeans that the same suggestion may not be repeated after deleting the code\nsuggestion. While Code Suggestions is in Beta, we are working on improving\nthe accuracy of generated content overall. Please review the [known\nlimitations](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#known-limitations),\nas this could affect your learning experience. \n\n\n## Learning a new programming language: Rust \n\nNow, let's dig into learning Rust, which is one of the [supported languages\nin Code\nSuggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#supported-languages). \n\n\n[Rust by Example](https://doc.rust-lang.org/rust-by-example/) provides a\ngreat tutorial for beginners, together with the official [Rust\nbook](https://doc.rust-lang.org/book/). The [Hands-on Rust\nbook](https://hands-on-rust.com/) shows how to build a 2D game as a more\npractical approach. More examples are shared in [this Rust book\nlist](https://github.com/sger/RustBooks). \n\n\nBefore diving into the source code, make sure to set up your development\nenvironment.\n\n\n### Development environment for Rust\n\n1) Create a new project `learn-rust-ai` in GitLab, and clone the project\ninto your development environment. All code snippets are available in [this\n\"Learn Rust with AI\"\nproject](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai).\n\n\n```shell\n\ngit clone https://gitlab.com/NAMESPACE/learn-rust-ai.git\n\n\ncd learn-rust-ai\n\n\ngit status\n\n```\n\n\n2) Install Rust and the build toolchain. Fortunately, this is\nstraightforward [following the Rust install\ndocumentation](https://www.rust-lang.org/tools/install).\n\n\nTip for using the generic installer: Download the script and run it after\nreview. \n\n\n```\n\n# Download and print the script before running it\n\ncurl -Lvs https://sh.rustup.rs -o rustup-init.sh\n\n\n# Run the Rust installer script\n\nsh rustup-init.sh \n\n```\n\n\nExample on macOS using Homebrew:\n\n\n```\n\nbrew install rust\n\n```\n\n\n1) Optional: Install the [rust-analyzer VS Code\nextension](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer).\n\n\n2) Each exercise will invite you to compile the code with the [`rustc`\ncommand](https://doc.rust-lang.org/rustc/what-is-rustc.html), and later\nusing [`cargo` as build tool and package\nmanager](https://doc.rust-lang.org/cargo/index.html).\n\n\nYou are all set to learn Rust! \n\n\n### Hello, World\n\nWe will start with [Rust by\nExample](https://doc.rust-lang.org/rust-by-example/), and follow the [Hello,\nWorld exercise](https://doc.rust-lang.org/rust-by-example/hello.html).\n\n\nCreate a new file `hello.rs` in the root directory of the project and start\nwith a comment saying `// Hello world`. Next, start writing the `main`\nfunction, and verify the code suggestion.\n\n\n![VS Code hello.rs Rust code suggestion, asking to\naccept](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_hello_world_suggested.png){:\n.shadow}\n\n\nAccept the suggestion by pressing the `tab` key and save the file (keyboard\nshortcut: cmd s). \n\n\n```\n\n// Hello world\n\n\nfn main() {\n    println!(\"Hello, world!\");\n}\n\n```\n\n\n![VS Code hello.rs Rust code suggestion,\naccepted](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_hello_world_accepted.png){:\n.shadow}\n\n\nCommit the change to the Git repository. In VS Code, use the keyboard\nshortcut `ctrl shift G`, add a commit message, and hit `cmd enter` to\nsubmit. \n\n\nUse the command palette (`cmd shift p`) and search for `create terminal` to\nopen a new terminal. \n\n\nBuild and run the code.\n\n\n```shell\n\nrustc hello.rs\n\n\n./hello\n\n```\n\n\n![hello.rs Rust code suggestion, accepted, compiled,\nrun](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_hello_world_cli_build.png){:\n.shadow}\n\n\nTip: Adding [code comments in Rust\n(`//`)](https://doc.rust-lang.org/reference/comments.html) before you start\nwriting a function or algorithm will help Code Suggestions with more context\nto provide better suggestions. In the example above, we did that with `//\nHello world`, and will continue doing so in the next exercises. \n\n\n## Cargo: Bringing structure into Rust\n\n[Cargo](https://doc.rust-lang.org/rust-by-example/cargo.html) is the\nofficial Rust package management tool. It is more than that - you can run\nbuild and test commands because Cargo understands them as well. \n\n\nYou can initialize a new Cargo configuration in the current directory tree\nwith the following command:\n\n\n```shell\n\ncargo init\n\n```\n\n\nThe directory tree invites you to add the source code into the `src/`\ndirectory, while `Cargo.toml` manages the dependencies and used compiler\nversions. The `.gitignore` file is also added including best practices. \n\n\n```shell\n\ntree\n\n.\n\n├── Cargo.toml\n\n├── README.md\n\n├── hello\n\n├── hello.rs\n\n└── src\n    └── main.rs\n```\n\n\nTry building the code and running it using `cargo`.\n\n\n```shell\n\ncargo build\n\n\ncargo run\n\n```\n\n\nCommit all changes and push them to your GitLab project.\n\n\n```shell\n\ngit commit -avm \"Initialize Cargo\"\n\n\ngit push\n\n```\n\n\nAfter exploring Cargo, let's make sure that our code is continuously tested\nwhile learning Rust. The next section explains how to set up [GitLab\nCI/CD](https://about.gitlab.com/topics/ci-cd/) for Rust. \n\n\n## Automation: Configure CI/CD pipeline for Rust\n\nThe [CI/CD pipeline](https://docs.gitlab.com/ee/ci/) should run two jobs in\ntwo stages: Build and test the code. The default container\n[image](https://docs.gitlab.com/ee/ci/yaml/#image), `rust:latest`, works in\nthe first iteration. In order to save resources, the CI/CD configuration\nalso supports [caching](https://docs.gitlab.com/ee/ci/caching/) for\ndownloaded dependencies and build objects. The `CARGO_HOME` variable is set\nto the CI/CD job home directory to ensure everything gets appropriately\ncached.\n\n\n```yaml\n\nstages:\n  - build\n  - test \n\ndefault:\n  image: rust:latest\n  cache:\n    key: ${CI_COMMIT_REF_SLUG}\n    paths:                      \n      - .cargo/bin\n      - .cargo/registry/index\n      - .cargo/registry/cache\n      - target/debug/deps\n      - target/debug/build\n    policy: pull-push\n\n# Cargo data needs to be in the project directory to be cached. \n\nvariables:\n  CARGO_HOME: ${CI_PROJECT_DIR}/.cargo      \n```\n\n\nThe CI/CD jobs inherit the\n[`default`](https://docs.gitlab.com/ee/ci/yaml/#default) values, and specify\nthe cargo commands in the [`script`\nsection](https://docs.gitlab.com/ee/ci/yaml/#script).\n\n\n```yaml\n\nbuild-latest:\n  stage: build\n  script:\n    - cargo build --verbose\n\ntest-latest:\n  stage: build\n  script:\n    - cargo test --verbose\n```\n\n\nYou can see an example in [this\nMR](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai/-/merge_requests/1/diffs).\n\n\n## Continue learning Rust \n\nMake sure to add new source code into the `src/` directory. \n\n\n### Define variables and print them\n\nPractice adding a few more\n[print](https://doc.rust-lang.org/rust-by-example/hello/print.html)\nstatements into `src/main.rs`, and then build and run the code again.\n\n\n1) Define a variable called `name` and assign your name as string value.\n\n\n2) Print the name, including a string prefix saying `Hello, `. \n\n\n![VS Code main.rs Rust code suggestion, first step in\nprint](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_print_variable_first.png){:\n.shadow}\n\n\n![VS Code main.rs Rust code suggestion, second step in\nprint](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_print_variable_second.png){:\n.shadow}\n\n\n1) Open a new terminal in VS Code using the command palette (keyboard\nshortcut `cmd + shift + p`) and search for `terminal`.\n\n\n2) Build and run the code with the `cargo build` and `cargo run` commands. \n\n\n![VS Code terminal with cargo build and run\noutput](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_print_variable_cargo_build_run_terminal.png){:\n.shadow}\n\n\nAn example solution can be found\n[here](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai/-/blob/main/solutions/variable_print.rs). \n\n\n### Explore variable types \n\nDefine different variable value types\n([primitives](https://doc.rust-lang.org/rust-by-example/primitives.html))\nand embed them into the `print` statements. Maybe they feel familiar with\nother programming languages?\n\n\nTip: Use code comments to see which code suggestions can be useful to learn.\nStart with typing `// Integer addition` and see what code suggestions you\ncan add.\n\n\n![VS Code main.rs Rust code suggestion, primitive types with literals and\nexpressions](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_primitive_types_literals_operators.png)\n\n\nExperiment with GitLab Duo Code Suggestions. The shown examples are\nnon-deterministic, but you may be able to add additions, subscriptions,\nmultiplications, etc., and the corresponding `println` statements just by\naccepting code suggestions and continuing the flow with `enter` or\ncompleting the code statements. This workflow can create a chain of code\nsuggestions that can help you learn the Rust language. \n\n\n![Literals and expressions, first\nsuggestion](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_literals_expressions_01.png){:\n.shadow}\n\n![Literals and expressions, second\nsuggestion](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_literals_expressions_02.png){:\n.shadow}\n\n![Literals and expressions, third\nsuggestion](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_literals_expressions_03.png){:\n.shadow}\n\n\nAn example solution can be found\n[here](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai/-/blob/main/solutions/literals_expressions.rs). \n\n\nThe code suggestions are not perfect. Sometimes there are errors that\nrequire you to fix the problems. When writing this blog post, I had to fix\ntwo missing semicolons at the end of the code lines. The great thing about\nthe Rust compiler is that the error messages tell you exactly where the\nproblem happens with suggestions to fix them. Code Suggestions and the\nRust-provided build chain make writing Rust code more efficient. \n\n\n```rust\n\nprintln!(\"Hello, {}!\", name)\n\n\n// Integer subtraction\n\nlet y = 9 - 4\n\n```\n\n\n![Terminal build, errors, Rust compiler\nhelp](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_terminal_errors_rust_help.png){:\n.shadow}\n\n\nYou can try to provoke the same error by removing a semicolon at the end of\na statement and then running `cargo build` in the terminal again. The Rust\ncompiler will also warn you about unused variables to help with better code\nquality. The screenshot shows warnings for variable definitions, and also a\nCLI command to fix them. \n\n\n![Terminal build, warnings, Rust compiler\nhelp](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_terminal_warnings_rust_help.png){:\n.shadow}\n\n\n### Flow control: Conditions and loops \n\nNext, let's focus on [flow\ncontrol](https://doc.rust-lang.org/rust-by-example/flow_control.html) with\nconditions, loops, etc., and how to implement them.\n\n\n1) Start typing `// Flow control` and see which suggestions are provided.\n\n\n2) Experiment with the code, and continue defining a boolean variable `v`\nwhich is set to true. \n\n\n```rust\n  // Flow control\n  let v = true;\n\n```\n\n\n![Conditions, boolean\nvariable](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_flow_control_conditions_01.png){:\n.shadow}\n\n![Conditions, boolean variable, if\ncondition](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_flow_control_conditions_02.png){:\n.shadow}\n\n\n1) Start typing `// Loops` and experiment with the code suggestions. \n\n\nLet's assume the loop looks the like following snippet. It does not have a\nloop counter which gets printed on every loop execution.\n\n\n```rust\n\n// Loops\n\nlet mut count = 0;\n\n\nloop {\n    count += 1;\n\n    if count == 10 {\n        break;\n    }\n}\n\n```\n\n\n2) Start typing `println!` and see which code suggestions are provided, for\nexample `println!(\"Count: {}\", count);`. \n\n\n![Loops, loop counter print\nsuggestion](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_flow_control_loops_print_counter.png)\n\n\n3) Apply the suggestions, and execute `cargo build && cargo run` on the\nterminal again. \n\n\nLet's learn more: Rust supports different loop types, for example [while\nloops](https://doc.rust-lang.org/rust-by-example/flow_control/while.html),\n[for\nloops](https://doc.rust-lang.org/rust-by-example/flow_control/for.html),\netc. \n\n\n1) Type `// While loop` and verify the code suggestions. Repeat the same for\n`// For loop`.\n\n\n```rust\n\n// While loops\n\nlet mut count = 0;\n\n\nwhile count \u003C 10 {\n    count += 1;\n    println!(\"Count: {}\", count);\n}\n\n\n// For loops\n\nlet a = [10, 2, 3, 4, 5];\n\n\nfor element in a {\n    println!(\"Element: {}\", element);\n}\n\n```\n\n\nThere is more to learn with loops and conditions: Iterate over arrays,\nlists, maps, slices. Practice with writing comments for `// Maps and sets`\nand `// Vectors and strings`. \n\n\n![Vectors,\nstrings](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_flow_control_vectors_strings.png){:\n.shadow}\n\n\n```rust\n  // Maps and sets\n  let mut scores = HashMap::new();\n\n  scores.insert(String::from(\"Blue\"), 10);\n  scores.insert(String::from(\"Yellow\"), 50);\n\n  for (key, value ) in &scores {\n      println!(\"{}: {}\", key, value);\n  }\n\n  // Vectors and strings\n  let mut v = Vec::new();\n\n  v.push(1);\n  v.push(2);\n\n  for element in &v {\n      println!(\"Element: {}\", element);\n  }  \n```\n\n\nThis snippet will fail because the `HashMap` type needs to be imported from\n`std::collections::HashMap`. Add the following line on top before the main\nfunction definition: \n\n\n```rust\n\nuse std::collections::HashMap;\n\n``` \n\n\n2) Build and run the code with `cargo build && cargo run`. \n\n\nAn example solution is provided\n[here](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai/-/blob/main/solutions/flow_control.rs).\n\n\n**Async exercise**: \n\n\n1) Modify the input values for the different data types, and build and run\nthe code again.\n\n\n2) Add a condition into the loops that print the items only when a specific\ncondition is met (for example, the number is odd or even). \n\n\n### Functions \n\n\n[Functions](https://doc.rust-lang.org/rust-by-example/fn.html) help increase\ncode readability and testability with unit tests. Practice creating\nfunctions with the following steps: \n\n\n1) Two functions `isEven` and `isOdd` to evaluate whether a number is even\nor odd.\n\n\n```rust\n\nfn isEven(x: i32) -> bool {\n    x % 2 == 0\n}\n\n\nfn isOdd(x: i32) -> bool {\n    x % 2 != 0\n}\n\n```\n\n\n2) `isPrime` function to check whether a given integer value is a prime\nnumber.\n\n\n```rust\n\nfn isPrime(x: i32) -> bool {\n    let mut i = 2;\n\n    while i * i \u003C= x {\n        if x % i == 0 {\n            return false;\n        } else {\n            i += 1;\n        }\n    } \n\n    return true\n}\n\n```\n\n\n3) Create an array of integer values, loop over it, and call the functions.\nLet GitLab Code Suggestions guide you with the implementation by starting to\ntype the if conditions followed by the function name. \n\n\n```rust\n  // Functions\n  let mut integers = vec![1, 2, 3, 4, 5];\n\n  for i in integers.iter() {\n\n      if (isEven(i)) {\n          println!(\"{} is even\", i);\n      }\n\n      if (isOdd(i)) { \n          println!(\"{} is odd\", i);\n      }\n\n      if (isPrime(i)) { \n          println!(\"{} is prime\", i);\n      }\n\n      println!(\"{}\", i);\n  }\n```\n\n\nNote that passing a reference value to a function may result in an error\nfrom the Rust compiler. Follow the suggestions and build the code again. \n\n\n```shell\n\n$ cargo build && cargo run \n\n\nerror[E0308]: mismatched types\n   --> src/main.rs:112:21\n    |\n112 |         if (isPrime(i)) { \n    |             ------- ^ expected `i32`, found `&{integer}`\n    |             |\n    |             arguments to this function are incorrect\n    |    \nnote: function defined here\n   --> src/main.rs:136:4\n    |\n136 | fn isPrime(x: i32) -> bool {\n    |    ^^^^^^^ ------\nhelp: consider dereferencing the borrow\n    |\n112 |         if (isPrime(*i)) { \n    |                     +\n```\n\n\nAn example solution is provided\n[here](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai/-/blob/main/solutions/functions.rs).\n\n\n**Async exercise**: Create a function `containsString` and test it with an\narray of string values, and a string to search for, in a loop. The\nscreenshot shows a potential implementation. \n\n\n![containsString function, and vector with string elements to test,\nsuggesting its usage in the main\nfunction](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_function_implemented_then_suggested_in_main.png){:\n.shadow}\n\n\n### Testing \n\nWhile learning programming, adopt\n[testing](https://doc.rust-lang.org/rust-by-example/testing.html) into your\nprocess. This can be unit tests for functions, documentation testing, and\nintegration testing. Practice with testing the previously created functions\n`isEven`, `isOdd`, and `isPrime`. Starty by typing `mod tests {` followed by\na new line with `use super::*` to implement the example from the [Rust\ndocumentation for unit\ntests](https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html).\n\n\n```rust\n\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_is_even() {\n        assert!(isEven(2)); \n        assert!(!isEven(3));\n    }\n\n    #[test] \n    fn test_is_odd() {\n        assert!(!isOdd(2));\n        assert!(isOdd(3));\n    }\n\n    #[test]\n    fn test_is_prime() { \n        assert!(isPrime(2));\n        assert!(!isPrime(3));\n    }\n}\n\n```\n\n\nRun `cargo test` to run the unit tests. Modify the test values to experiment\nwith the results. \n\n\n```shell\n\ncargo test\n\n```\n\n\n![Function unit tests, cargo test output in the VS Code\nterminal](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_function_unit_tests_terminal_run.png)\n\n\nCreate unit tests that fail, and commit and push the changes to GitLab. The\nCI/CD pipelines will fail in this simulated breakage. The example above\nneeds a fix for the `test_is_prime` test. Commit and push the change to\nverify that the pipeline passes again. \n\n\n```diff\n\n-        assert!(!isPrime(3));\n\n+        assert!(!isPrime(4));\n\n```\n\n\n## What is next \n\nIn an upcoming blog, we will look into advanced learning examples with\nasynchronous operations, services and external API communication in future\nblog posts. Until then, here are a few recommendations for practicing async.\n\n\n### Async learning exercises\n\n- [`std misc`](https://doc.rust-lang.org/rust-by-example/std_misc.html)\nprovides asynchronous operations with threads, channels and file I/O\n\n- Book: [Hands-on Rust: Effective Learning through 2D Game Development and\nPlay](https://pragprog.com/titles/hwrust/hands-on-rust/)\n\n- Tutorial: [Are we game yet?](https://arewegameyet.rs/resources/tutorials/)\n\n- Use case: [Web server with\nrocket.rs](https://rocket.rs/v0.5-rc/guide/quickstart/#running-examples)\n\n\nHere are a few more exercises and ideas for additional learning:\n\n1) The Rust compiler might have created warnings that need to be addressed.\nFollow the instructions from the `cargo build` commands and check the Git\ndiff. \n\n\n```\n\ncargo fix --bin \"learn-rust-ai\"\n\n\ngit diff \n\n```\n\n\n2) [Error handling](https://doc.rust-lang.org/rust-by-example/error.html) is\nrequired when failure is detected, and the caller should know. Some errors\ncan be recovered from within the application, others require program\ntermination. \n\n\n3) The [`std` library](https://doc.rust-lang.org/rust-by-example/std.html)\nextends primitive types and makes programming more efficient. \n\n\n### Share your feedback\n\nWhich programming language are you learning or considering learning? Start a\nnew topic on our [community](/community/) forum or Discord and share your\nexperience.  \n\n\nIf you are using Code Suggestions Beta with [GitLab Duo](/gitlab-duo/)\nalready, please share your thoughts and feedback [in this\nissue](https://gitlab.com/gitlab-org/gitlab/-/issues/405152).\n",[9,761,827,1016,717],{"slug":2772,"featured":6,"template":698},"learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started","content:en-us:blog:learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started.yml","Learning Rust With A Little Help From Ai Code Suggestions Getting Started","en-us/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started.yml","en-us/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started",{"_path":2778,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2779,"content":2785,"config":2791,"_id":2793,"_type":14,"title":2794,"_source":16,"_file":2795,"_stem":2796,"_extension":19},"/en-us/blog/machine-learning-and-devsecops",{"title":2780,"description":2781,"ogTitle":2780,"ogDescription":2781,"noIndex":6,"ogImage":2782,"ogUrl":2783,"ogSiteName":686,"ogType":687,"canonicalUrls":2783,"schema":2784},"Machine learning and DevSecOps: Inside the OctoML/GitLab integration","MLOps and DevSecOps teams can unify their workflows and gain automation and cost efficiencies.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749666915/Blog/Hero%20Images/autodevops.jpg","https://about.gitlab.com/blog/machine-learning-and-devsecops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Machine learning and DevSecOps: Inside the OctoML/GitLab integration\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sameer Farooqui, OctoML\"}],\n        \"datePublished\": \"2023-02-23\",\n      }",{"title":2780,"description":2781,"authors":2786,"heroImage":2782,"date":2788,"body":2789,"category":10,"tags":2790},[2787],"Sameer Farooqui, OctoML","2023-02-23","\n\nMachine learning can be a powerful tool in software development, but not if it has to live apart from existing engineering workflows. DevSecOps teams, including MLOps, can now integrate [OctoML CLI](https://gitlab.com/octoml/octoml-public/octoml-cli-tutorials) into [GitLab’s CI/CD Pipelines](https://docs.gitlab.com/ee/ci/pipelines/) to unify workflows and leverage existing deployment and monitoring infrastructure. This integration makes it easier to catch bugs and model performance degradations early in the ML development cycle. \n\nThe OctoML Platform is a machine learning model optimization and deployment service powered by octoml.ai. [Machine learning has grown in popularity](/blog/top-10-ways-machine-learning-may-help-devops/) in DevSecOps, along with AI, because of its ability to learn and model how to perform complex tasks as a human would and then automate those tasks.\n\n## How does CI/CD apply to machine learning?\n\nOnce a machine learning model has been successfully deployed, it can get stale over time and its accuracy could degrade, a situation called “data drift”. Data drift causes newer inferencing data to drift away from the data used to train the model. In the retail industry, this can happen because of seasonality, as an example.\n\nProduction models must be regularly refreshed by retraining their weights with the latest data. Applying CI/CD concepts borrowed from software engineering, the OctoML CI integration makes the deployment process for trained/re-trained models automated and repeatable.\n\n## How OctoML CLI and GitLab work together\n\nNew commits to your inference code repository can run [OctoML CLI](https://github.com/octoml/octoml-cli-tutorials#readme) in your GitLab pipeline to automatically optimize machine learning models for lowest cost per inference and lowest latency, and then deploy the optimized model to your cloud registry. For customers looking for more granular packaging formats that integrate with existing containerization systems, OctoML offers [Python wheel packaging](https://app.octoml.ai/docs/deploy.html#python-wheel-deployment) and will soon offer YAML configuration files. To reduce model latency and serving costs, OctoML searches through multiple acceleration engines such as Apache TVM, ONNX Runtime, and TensorRT and then suggests the ideal CPU or GPU hardware type on AWS, Azure, or GCP.\n\n## Choice in cloud deployment targets\n\nUsing OctoML CLI, developers can send any trained model to OctoML’s SaaS platform for cost efficiency and cloud hardware benchmarking. By adapting and optimizing the trained model to leverage hardware intrinsics in CPU and GPUs, OctoML makes inferences run faster in production, thus saving users on cost per inference and improving the user experience of ML applications.\n\n![Cloud workflow](https://about.gitlab.com/images/blogimages/octomlintegration/image1.png){: .shadow}\n\nThe cloud workflow is designed for enterprise and production deployments. Here’s how it works:\n\n* The initial push from a developer to the GitLab repository launches a local, shared, or remote runner.\n* The runner will send the updated, trained model first to OctoML’s platform for acceleration and hardware adaptation.\n* Then, the pipeline pushes the accelerated model container to the GitLab Container Registry.\n* Finally, it deploys the container to a managed Kubernetes service in any of the major cloud providers.\n\nModels deployed via the accelerated cloud workflow not only provide end users the lowest latency user experience but also save the organization compute costs at inference time, which can amount to \\[90% of a production machine learning application’s compute costs](https://aws.amazon.com/blogs/machine-learning/reduce-ml-inference-costs-on-amazon-sagemaker-with-hardware-and-software-acceleration/).\n\n## Four required stages for every pipeline\n\nEach pipeline has four stages: setup, package, deploy, and test. Here’s the logical flow:\n\n![Logical flow](https://about.gitlab.com/images/blogimages/octomlintegration/image2.png){: .shadow}\n\n1. common:setup - produces OctoML CLI binary artifact and passes it on to local:package\n2. cloud:package - packages the incoming model into a Docker tarball using the OctoML CLI binary and passes the tarball to the next stage\n3. cloud:deploy - builds a Docker image from the Tarball and deploys the docker container to a remote registry (in our example, we deploy it to AWS via GitLab Container Registry using Flux, but there can be other mechanisms)\n4. cloud:test - run the user-provided test script\n\nWhen a cloud pipeline is executed, the GitLab Pipeline UI will display a corresponding workflow:\n\n![GitLab Pipeline UI](https://about.gitlab.com/images/blogimages/octomlintegration/image3.png){: .shadow}\n\nSimilar to any other GitLab CI/CD job, our [example repository](https://gitlab.com/octoml/octoml-public/octoml-cli-tutorials) has YAML files that define how each stage will execute. You can easily clone the repository or code and adapt it to your custom model and inference code:\n\n![example repository](https://about.gitlab.com/images/blogimages/octomlintegration/image4.png){: .shadow}\n\nIn addition to the stage YAML files, OctoML CLI also has its own `octoml.yaml` configuration, which defines the path to your model, hardware type the model should be accelerated for, and the model’s input shapes:\n\n![octoml.yaml config](https://about.gitlab.com/images/blogimages/octomlintegration/image5.png){: .shadow}\n\n## Get started with OctoML CLI and GitLab CI/CD\n\nOctoML CLI and GitLab CI/CD unify your software engineering and machine learning pipelines by allowing ML models to be deployed using the same infrastructure and processes you’re currently using for software applications. Further, our integration makes it seamless to start with local model deployments to test end-to-end inference and move to accelerated cloud deployments with minimal changes to your workflow.\n\n**We’ve [published tutorials](https://gitlab.com/octoml/octoml-public/octoml-cli-tutorials) with an NLP (Bertsquad) and Vision (YOLOv5) model for end-to-end examples. So, to get started, download the [OctoML CLI](https://try.octoml.ai/cli/) and [request an acceleration consultation](https://try.octoml.ai/cli/#lp-pom-block-105) to receive a token to OctoML’s SaaS platform.**\n",[233,717,9],{"slug":2792,"featured":6,"template":698},"machine-learning-and-devsecops","content:en-us:blog:machine-learning-and-devsecops.yml","Machine Learning And Devsecops","en-us/blog/machine-learning-and-devsecops.yml","en-us/blog/machine-learning-and-devsecops",{"_path":2798,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2799,"content":2805,"config":2811,"_id":2813,"_type":14,"title":2814,"_source":16,"_file":2815,"_stem":2816,"_extension":19},"/en-us/blog/managing-gitlab-resources-with-pulumi",{"title":2800,"description":2801,"ogTitle":2800,"ogDescription":2801,"noIndex":6,"ogImage":2802,"ogUrl":2803,"ogSiteName":686,"ogType":687,"canonicalUrls":2803,"schema":2804},"Managing GitLab resources with Pulumi","Learn how Pulumi's infrastructure-as-code tool helps streamline the automation of GitLab CI/CD workflows.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683430/Blog/Hero%20Images/AdobeStock_293854129__1_.jpg","https://about.gitlab.com/blog/managing-gitlab-resources-with-pulumi","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Managing GitLab resources with Pulumi\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Josh Kodroff, Pulumi\"}],\n        \"datePublished\": \"2024-01-10\",\n      }",{"title":2800,"description":2801,"authors":2806,"heroImage":2802,"date":2808,"body":2809,"category":10,"tags":2810},[2807],"Josh Kodroff, Pulumi","2024-01-10","In the ever-evolving landscape of DevOps, platform engineers are\nincreasingly seeking efficient and flexible tools to manage their GitLab\nresources, particularly for orchestrating continuous integration/continuous\ndelivery (CI/CD) pipelines.\n[Pulumi](https://pulumi.com?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources)\noffers a unique approach to infrastructure as code (IaC) by allowing\nengineers to use familiar programming languages such as TypeScript, Python,\nGo, and others. This approach streamlines the automation of GitLab CI/CD\nworkflows. Pulumi's declarative syntax, combined with its ability to treat\ninfrastructure as software, facilitates version control, collaboration, and\nreproducibility, aligning seamlessly with the GitLab philosophy.\n\n\nLet's explore the power of using Pulumi and GitLab.\n\n\n## What is Pulumi?\n\n\nPulumi is an IaC tool that allows you to manage resources in more than 150\nsupported cloud or SaaS products (including AWS and GitLab, which we will be\ndemonstrating in this post). You can express your infrastructure with Pulumi\nusing popular general-purpose programming languages like TypeScript, Python,\nand Go.\n\n\nPulumi is declarative (just like other popular IaC tools you may be familiar\nwith), which means that you only need to describe the desired end state of\nyour resources and Pulumi will figure out the order of create, read, update,\nand delete (CRUD) operations to get from your current state to your desired\nstate.\n\n\nIt might seem strange at first to use a general-purpose programming language\nto express your infrastructure's desired state if you're used to tools like\nCloudFormation or Terraform, but there are considerable advantages to\nPulumi's approach, including the following:\n\n- **Familiar tooling.** You don't need any special tooling to use Pulumi.\nCode completion will work as expected in your favorite editor or IDE without\nany additional plugins. You can share Pulumi code using familiar packaging\ntools like npm, PyPI, etc.\n\n- **Familiar syntax.** Unlike with DSL-based IaC tools, you don't need to\nlearn special ways of indexing an array element, or creating loops or\nconditionals - you can just use the normal syntax of a language you already\nknow.\n\n\nThe Pulumi product has an open source component, which includes the Pulumi\ncommand line and its ecosystem of providers, which provide the integration\nbetween Pulumi and the cloud and SaaS providers it supports. Pulumi also\noffers a free (for individual use) and paid (for teams and organizations)\nSaaS service called Pulumi Cloud, which provides state file and secrets\nmanagement, among many other useful features. It’s a widely-supported\nopen-source IaC tool.\n\n\n## Initializing the project\n\n\nTo complete this example you'll need:\n\n\n1. [A Pulumi Cloud\naccount](https://app.pulumi.com?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources).\nPulumi Cloud is free for individual use forever and we'll never ask for your\ncredit card. Pulumi Cloud will manage your Pulumi state file and handle any\nsecrets encryption/decryption. Because it's free for individual use (no\ncredit card required), we strongly recommend that you use Pulumi Cloud as\nyour backend when learning how to use Pulumi.\n\n2. A GitLab account, group, and a GitLab token set to the `GITLAB_TOKEN`\nenvironment variable.\n\n3. An AWS account and credentials with permissions to deploy identity and\naccess management (IAM) resources. For details on how to configure AWS\ncredentials on your system for use with Pulumi, see [AWS Classic:\nInstallation and\nConfiguration](https://www.pulumi.com/registry/packages/aws/installation-configuration/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources).\n\n\nThis example will use two providers from the [Pulumi\nRegistry](https://www.pulumi.com/registry/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources):\n\n\n1. The [GitLab\nProvider](https://www.pulumi.com/registry/packages/gitlab/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources)\nwill be used to manage resources like Projects, ProjectFiles (to initialize\nour project repository), ProjectHooks (for the integration with Pulumi\nCloud), and ProjectVariables (to hold configuration for our CI/CD\npipelines).\n\n2. The [AWS Classic\nProvider](https://www.pulumi.com/registry/packages/aws/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources)\nwill be used to manage AWS resources to create OpenID Connect (OIDC)\nconnectivity between AWS and GitLab.\n\n\nYou can initialize your Pulumi project by changing into a new, empty\ndirectory, running the following command, and accepting all the default\nvalues for any subsequent prompts:\n\n\n```bash\n\npulumi new typescript\n\n```\n\n\nThis will bootstrap an empty Pulumi program. Now you can import the provider\nSDKs for the providers you'll need:\n\n\n```bash\n\nnpm i @pulumi/aws @pulumi/gitlab\n\n```\n\n\nYour `index.ts` file is the entry point into your Pulumi program (just as\nyou would expect in any other Node.js program) and will be the file to which\nyou will add your resources. Add the following imports to the top of\n`index.ts`:\n\n\n```typescript\n\nimport * as gitlab from \"@pulumi/gitlab\";\n\nimport * as aws from \"@pulumi/aws\";\n\n```\n\n\nNow you are ready to add some resources!\n\n\n## Adding your first resources\n\n\nFirst, let's define a variable that will hold the audience claim in our OIDC\nJWT token. Add the following code to `index.ts`:\n\n\n```typescript\n\nconst audience = \"gitlab.com\";\n\n```\n\n\nThe above code assume you're using the GitLab SaaS (\u003Chttps://gitlab.com>) If\nyou are using a private GitLab install, your value should be the domain of\nyour GitLab install, e.g. `gitlab.example.com`.\n\n\nThen, you'll use a [Pulumi\nfunction](https://www.pulumi.com/docs/concepts/resources/functions/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources)\nto grab an existing GitLab group by name and create a new public GitLab\nproject in your GitLab group:\n\n\n```typescript\n\nconst group = gitlab.getGroup({\n  fullPath: \"my-gitlab-group\", // Replace the value with the name of your GL group\n});\n\n\nconst project = new gitlab.Project(\"pulumi-gitlab-demo\", {\n  visibilityLevel: \"public\",\n  defaultBranch: \"main\",\n  namespaceId: group.then(g => parseInt(g.id)),\n  archiveOnDestroy: false // Be sure to set this to `true` for any non-demo repos you manage with Pulumi!\n});\n\n```\n\n\n## Creating OIDC resources\n\n\nTo allow GitLab CI/CD to request and be granted temporary AWS credentials,\nyou'll need to create an OIDC provider in AWS that contains the thumbprint\nof GitLab's certificate, and then create an AWS role that GitLab is allowed\nto assume.\n\n\nYou'll scope the assume role policy so that the role can be only be assumed\nby the GitLab project you declared earlier. The role that GitLab CI/CD\nassumed will have full administrator access so that Pulumi can create and\nmanage any resource within AWS. (Note that it is possible to grant less than\n`FullAdministrator` access to Pulumi, but `FullAdministrator` is often\npractically required, e.g. where IAM resources, like roles, need to be\ncreated. Role creation requires `FullAdministrator`. This consideration also\napplies to IaC tools like Terraform.)\n\n\nAdd the following code to `index.ts`:\n\n\n```typescript\n\nconst GITLAB_OIDC_PROVIDER_THUMBPRINT =\n\"b3dd7606d2b5a8b4a13771dbecc9ee1cecafa38a\";\n\n\nconst gitlabOidcProvider = new\naws.iam.OpenIdConnectProvider(\"gitlab-oidc-provider\", {\n  clientIdLists: [`https://${audience}`],\n  url: `https://${audience}`,\n  thumbprintLists: [GITLAB_OIDC_PROVIDER_THUMBPRINT],\n}, {\n  deleteBeforeReplace: true, // URLs are unique identifiers and cannot be auto-named, so we have to delete before replace.\n});\n\n\nconst gitlabAdminRole = new aws.iam.Role(\"gitlabAdminRole\", {\n  assumeRolePolicy: {\n    Version: \"2012-10-17\",\n    Statement: [\n      {\n        Effect: \"Allow\",\n        Principal: {\n          Federated: gitlabOidcProvider.arn,\n        },\n        Action: \"sts:AssumeRoleWithWebIdentity\",\n        Condition: {\n          StringLike: {\n            // Note: Square brackets around the key are what allow us to use a\n            // templated string. See:\n            // https://stackoverflow.com/questions/59791960/how-to-use-template-literal-as-key-inside-object-literal\n            [`${audience}:sub`]: pulumi.interpolate`project_path:${project.pathWithNamespace}:ref_type:branch:ref:*`\n          },\n        },\n      },\n    ],\n  },\n});\n\n\nnew aws.iam.RolePolicyAttachment(\"gitlabAdminRolePolicy\", {\n  policyArn: \"arn:aws:iam::aws:policy/AdministratorAccess\",\n  role: gitlabAdminRole.name,\n});\n\n```\n\n\nA few things to be aware of regarding the thumbprint:\n\n\n1. If you are self-hosting GitLab, you'll need to obtain the thumbprint from\nyour private GitLab installation.\n\n2. If you're using GitLab SaaS, it's possible GitLab's OIDC certificate may\nhave been rotated by the time you are reading this.\n\n\nIn either case, you can obtain the correct/latest thumbprint value by\nfollowing AWS' instructions contained in [Obtaining the thumbprint for an\nOpenID Connect Identity\nProvider](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html)\nin the AWS docs.\n\n\nYou'll also need to add the role's ARN as a project variable so that the\nCI/CD process can make a request to assume the role:\n\n\n```typescript\n\nnew gitlab.ProjectVariable(\"role-arn\", {\n  project: project.id,\n  key: \"ROLE_ARN\",\n  value: gitlabAdminRole.arn,\n});\n\n```\n\n\n## Project hook (optional)\n\n\nPulumi features an integration with GitLab via a webhook that will post the\noutput of the `pulumi preview` directly to a merge request as a comment. For\nthe webhook to work, you must have a Pulumi organization set up with GitLab\nas its SSO source. If you don't have a Pulumi organization and would like to\ntry the integration, you can [sign up for a free\ntrial](https://app.pulumi.com/signup?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources)\norganization. The trial lasts 14 days, will give you access to all of\nPulumi's paid features, and does not require a credit card. For full details\non the integration, see [Pulumi CI/CD & GitLab\nintegration](https://www.pulumi.com/docs/using-pulumi/continuous-delivery/gitlab-app/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources).\n\n\nTo set up the webhook, add the following to your `index.ts` file:\n\n\n```typescript\n\nnew gitlab.ProjectHook(\"project-hook\", {\n  project: project.id,\n  url: \"https://api.pulumi.com/workflow/gitlab\",\n  mergeRequestsEvents: true,\n  enableSslVerification: true,\n  token: process.env[\"PULUMI_ACCESS_TOKEN\"]!,\n  pushEvents: false,\n});\n\n```\n\n\nNote that the above resource assumes that your Pulumi access token is stored\nas an environment variable. You may want to instead store the token in your\nstack configuration file. To do this, run the following command:\n\n\n```bash\n\npulumi config set --secret pulumiAccessToken ${PULUMI_ACCESS_TOKEN}\n\n```\n\n\nThis will store the encrypted value in your Pulumi stack configuration file\n(`Pulumi.dev.yaml`). Because the value is encrypted, you can safely commit\nyour stack configuration file to git. You can access its value in your\nPulumi program like this:\n\n\n```typescript\n\nconst config = new pulumi.Config();\n\nconst pulumiAccessToken = config.requireSecret(\"pulumiAccessToken\");\n\n```\n\n\nFor more details on secrets handling in Pulumi, see\n[Secrets](https://www.pulumi.com/docs/concepts/secrets/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources)\nin the Pulumi docs.\n\n\n## Creating a repository and adding repository files\n\n\nYou'll need to create a git repository (a GitLab project) and add some files\nto it that will control the CI/CD process. First, create some files that\nyou'll include in your GitLab repo:\n\n\n```bash\n\nmkdir -p repository-files/scripts\n\ntouch repository-files/.gitlab-ci.yml\nrepository-files/scripts/{aws-auth.sh,pulumi-preview.sh,pulumi-up.sh}\n\nchmod +x\nrepository-files/scripts/{aws-auth.sh,pulumi-preview.sh,pulumi-up.sh}\n\n```\n\n\nNext, you'll need a GitLab CI/CD YAML file to describe the pipeline: which\ncontainer image it should be run in and what the steps of the pipeline are.\nPlace the following code into `repository-files/.gitlab-ci.yml`:\n\n\n```yaml\n\ndefault:\n  image:\n    name: \"pulumi/pulumi:3.91.1\"\n    entrypoint: [\"\"]\n\nstages:\n  - infrastructure-update\n\npulumi-up:\n  stage: infrastructure-update\n  id_tokens:\n    GITLAB_OIDC_TOKEN:\n      aud: https://gitlab.com\n  before_script:\n    - chmod +x ./scripts/*.sh\n    - ./scripts/aws-auth.sh\n  script:\n    - ./scripts/pulumi-up.sh\n  only:\n    - main # i.e., the name of the default branch\n\npulumi-preview:\n  stage: infrastructure-update\n  id_tokens:\n    GITLAB_OIDC_TOKEN:\n      aud: https://gitlab.com\n  before_script:\n    - chmod +x ./scripts/*.sh\n    - ./scripts/aws-auth.sh\n  script:\n    - ./scripts/pulumi-preview.sh\n  rules:\n    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'\n```\n\n\nThe CI/CD process is fairly simple but illustrates the basic functionality\nneeded for a production-ready pipeline (or these steps may be all your\norganization needs):\n\n\n1. Run the `pulumi preview` command when a merge request is opened or\nupdated. This will help the reviewer gain important context. Because IaC is\nnecessarily stateful (the state file is what enables Pulumi to be a\ndeclarative tool), when reviewing changes reviewers _must have both the code\nchanges and the infrastructure changes to fully understand the impact of\nchanges to the codebase_. This process constitutes continuous integration.\n\n2. Run the `pulumi up` command when code is merged to the default branch\n(called `main` by default). This process constitutes continuous delivery.\n\n\nNote that this example uses the\n[`pulumi/pulumi`](https://hub.docker.com/r/pulumi/pulumi) \"kitchen sink\"\nimage that contains all the runtimes for all the languages Pulumi supports,\nalong with some ancillary tools like the AWS CLI (which you'll need in order\nto use OIDC authentication). While the `pulumi/pulumi` image is convenient,\nit's also quite large (1.41 GB at the time of writing), which makes it\nrelatively slow to initialize. If you're creating production pipelines using\nPulumi, you may want to consider creating your own custom (slimmer) image\nthat has exactly the tools you need installed, perhaps starting with one of\nPulumi's language-specific images, e.g.\n[`pulumi/pulumi-nodejs`](https://hub.docker.com/r/pulumi/pulumi-nodejs).\n\n\nThen you'll need to write the script that authenticates GitLab with AWS via\nOIDC. Place the following code in `repository-files/scripts/aws-auth.sh`:\n\n\n```bash\n\n#!/bin/bash\n\n\nmkdir -p ~/.aws\n\necho \"${GITLAB_OIDC_TOKEN}\" > /tmp/web_identity_token\n\necho -e \"[profile\noidc]\\nrole_arn=${ROLE_ARN}\\nweb_identity_token_file=/tmp/web_identity_token\"\n> ~/.aws/config\n\n\necho \"length of GITLAB_OIDC_TOKEN=${#GITLAB_OIDC_TOKEN}\"\n\necho \"ROLE_ARN=${ROLE_ARN}\"\n\n\nexport AWS_PROFILE=\"oidc\"\n\naws sts get-caller-identity\n\n```\n\n\nFor continuous integration, you'll need a script that will execute the\n`pulumi preview` command when a merge request is opened. Place the following\ncode in `repository-files/scripts/pulumi-preview.sh`:\n\n\n```bash\n\n#!/bin/bash\n\nset -e -x\n\n\nexport PATH=$PATH:$HOME/.pulumi/bin\n\n\nyarn install\n\npulumi login\n\npulumi org set-default $PULUMI_ORG\n\npulumi stack select dev\n\nexport AWS_PROFILE=\"oidc\"\n\npulumi preview\n\n```\n\n\nFor continuous delivery, you'll need a similar script that will execute the\n`pulumi up` command when the Merge Request is merged to the default branch.\nPlace the following code in `repository-files/scripts/pulumi-up.sh`:\n\n\n```bash\n\n#!/bin/bash\n\nset -e -x\n\n\n# Add the pulumi CLI to the PATH\n\nexport PATH=$PATH:$HOME/.pulumi/bin\n\n\nyarn install\n\npulumi login\n\npulumi org set-default $PULUMI_ORG\n\npulumi stack select dev\n\nexport AWS_PROFILE=\"oidc\"\n\npulumi up -y\n\n```\n\n\nFinally, you'll need to add these files to your GitLab Project. Add the\nfollowing code block to your `index.ts` file:\n\n\n```typescript\n\n[\n  \"scripts/aws-auth.sh\",\n  \"scripts/pulumi-preview.sh\",\n  \"scripts/pulumi-up.sh\",\n  \".gitlab-ci.yml\",\n].forEach(file => {\n  const content = fs.readFileSync(`repository-files/${file}`, \"utf-8\");\n\n  new gitlab.RepositoryFile(file, {\n    project: project.id,\n    filePath: file,\n    branch: \"main\",\n    content: content,\n    commitMessage: `Add ${file},`,\n    encoding: \"text\",\n  });\n});\n\n```\n\n\nNote that we're able to take advantage of general-purpose programming\nlanguage features: We are able to create an array and use `forEach()` to\niterate through its members, and we are able to use the `fs.readFileSync()`\nmethod from the Node.js runtime to read the contents of our file. This is\npowerful stuff!\n\n\n## Project variables and stack outputs\n\n\nYou'll need a few more resources to complete the code. Your CI/CD process\nwill need a Pulumi access token in order to authenticate against the Pulumi\nCloud backend which holds your Pulumi state file and handles encryption and\ndecryption of secrets. You will also need to supply name of your Pulumi\norganization. (If you are using Pulumi Cloud as an individual, this is your\nPulumi username.) Add the following to `index.ts`:\n\n\n```typescript\n\nnew gitlab.ProjectVariable(\"pulumi-access-token\", {\n  project: project.id,\n  key: \"PULUMI_ACCESS_TOKEN\",\n  value: process.env[\"PULUMI_ACCESS_TOKEN\"]!,\n  masked: true,\n});\n\n\nnew gitlab.ProjectVariable(\"pulumi-org\", {\n  project: project.id,\n  key: \"PULUMI_ORG\",\n  value: pulumi.getOrganization(),\n});\n\n```\n\n\nFinally, you'll need to add a stack output so that we can run the `git\nclone` command to test out our pipeline. Stack outputs allow you to access\nvalues within your Pulumi program from the command line or from other Pulumi\nprograms. For more information, see [Understanding Stack\nOutputs](https://www.pulumi.com/learn/building-with-pulumi/stack-outputs/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources).\nAdd the following to `index.ts`:\n\n\n```typescript\n\nexport const gitCloneCommand = pulumi.interpolate`git clone\n${project.sshUrlToRepo}`;\n\n```\n\n\n## Deploying your infrastructure and testing the pipeline\n\n\nTo deploy your resources, run the following command:\n\n\n```bash\n\npulumi up\n\n```\n\n\nPulumi will output a list of the resources it intends to create. Select\n`yes` to continue.\n\n\nOnce the command has completed, you can run the following command to get the\ngit clone command for your GitLab repo:\n\n\n```bash\n\npulumi stack output gitCloneCommand\n\n```\n\n\nIn a new, empty directory, run the `git clone` command from your Pulumi\nstack output, e.g.:\n\n\n```bash\n\ngit clone git@gitlab.com:jkodroff/pulumi-gitlab-demo-9de2a3b.git\n\n```\n\n\nChange into the directory and create a new branch:\n\n\n```bash\n\ngit checkout -b my-first-branch\n\n```\n\n\nNow you are ready to create some sample infrastructure in our repository.\nYou can use the `aws-typescript` to quickly generate a simple Pulumi program\nwith AWS resources:\n\n\n```bash\n\npulumi new aws-typescript -y --force\n\n```\n\n\nThe template includes a very simple Pulumi program that you can use to prove\nout the pipeline:\n\n\n```bash\n\n$ cat index.ts\n\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport * as aws from \"@pulumi/aws\";\n\nimport * as awsx from \"@pulumi/awsx\";\n\n\n// Create an AWS resource (S3 Bucket)\n\nconst bucket = new aws.s3.Bucket(\"my-bucket\");\n\n\n// Export the name of the bucket\n\nexport const bucketName = bucket.id;\n\n```\n\n\nCommit your changes and push your branch:\n\n\n```bash\n\ngit add -A\n\ngit commit -m \"My first commit.\"\n\ngit push\n\n```\n\n\nIn the GitLab UI, create a merge request for your branch:\n\n\n![Screenshot demonstrating opening a GitLab Merge\nRequest](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683438/Blog/Content%20Images/create-merge-request.jpg)\n\n\nYour merge request pipeline should start running:\n\n\n![Screenshot demonstrating opening a GitLab Merge\nRequest](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683438/Blog/Content%20Images/merge-request-running.jpg)\n\n\nOnce the pipeline completes, you should see the output of the `pulumi\npreview` command in the pipeline's logs:\n\n\n![Screenshot of a GitLab pipeline log showing the output of the \"pulumi\npreview\"\ncommand](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683438/Blog/Content%20Images/pulumi-preview.jpg)\n\n\nIf you installed the optional webhook, you should see the results of `pulumi\npreview` posted back to the merge request as a comment:\n\n\n![Screenshot of the GitLab Merge Request screen showing the output of the\n\"pulumi preview\" command as a\ncomment](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683438/Blog/Content%20Images/merge-request-comment.jpg)\n\n\nOnce the pipeline has completed running, your merge request is ready to\nmerge:\n\n\n![Screenshot of the GitLab Merge Request screen showing a successfully\ncompleted\npipeline](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683438/Blog/Content%20Images/merge.jpg)\n\n\nMerging the merge request will trigger the main branch pipeline. (Note that\nin this screen you will see a failed initial run of CI/CD on the main branch\ntoward the bottom of the screen. This is normal and is caused by the initial\nupload of `.gitlab-ci/yml` to the main branch without a Pulumi program being\npresent.)\n\n\n![Screenshot of the GitLab pipelines screen showing a running pipeline along\nwith a passed\npipelines](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683438/Blog/Content%20Images/piplines.jpg)\n\n\nIf you click into the main branch pipeline's execution, you can see your\nbucket has been created:\n\n\n![Screenshot of a GitLab pipeline log showing the output of the \"pulumi up\"\ncommand](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683438/Blog/Content%20Images/pulumi-up.jpg)\n\nTo delete the bucket, run the following command in your local clone of the\nrepository:\n\n\n```bash\n\npulumi destroy\n\n```\n\n\nAlternatively, you could create a merge request that removes the bucket from\nyour Pulumi program and run the pipelines again. Because Pulumi is\ndeclarative, removing the bucket from your program will delete it from AWS.\n\n\nFinally, run the `pulumi destroy` command again in the Pulumi program with\nyour OIDC and GitLab resources to finish cleaning up.\n\n\n## Next steps\n\n\nUsing IaC to define pipelines and other GitLab resources can greatly improve\nyour platform team's ability to reliably and quickly manage the resources to\nkeep application teams delivering. With Pulumi, you also get the power and\nexpressiveness of using popular programming languages to express those\nresources!\n\n\nIf you liked what you read here, here are some ways you can enhance your\nCI/CD pipelines:\n\n\n- Add [Pulumi Policy\nPacks](https://www.pulumi.com/docs/using-pulumi/crossguard/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources)\nto your pipeline: Pulumi policy packs allow you to validate that your\nresources are in compliance with your organization's security and compliance\npolicies. Pulumi's open source [Compliance Ready\nPolicies](https://www.pulumi.com/docs/using-pulumi/crossguard/compliance-ready-policies/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources)\nare a great place to start on your journey. Compliance Ready Policies\ncontain policy rules for the major cloud providers for popular compliance\nframeworks like PCI-DSS and ISO27001, and policy packs are easy to integrate\ninto your pipelines.\n\n- Check out [Pulumi ESC (Environments, Secrets, and\nConfiguration)](https://www.pulumi.com/product/esc/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources):\nPulumi ESC makes it easy to share static secrets like GitLab tokens and can\neven [generate dynamic secrets like AWS OIDC\ncredentials](https://www.pulumi.com/blog/esc-env-run-aws/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources).\nESC becomes especially useful when using Pulumi at scale because it reduces\nthe duplication of configuration and secrets that are used by multiple\nPulumi programs. You don't even have to use Pulumi IaC to benefit from\nPulumi ESC - [Pulumi ESC's command\nline](https://www.pulumi.com/docs/esc-cli/commands/?utm_source=GitLab&utm_medium=Referral&utm_campaign=Managing-GitLab-Resources)\ncan be used with any CLI tool like the AWS CLI.\n",[109,9,284,233],{"slug":2812,"featured":6,"template":698},"managing-gitlab-resources-with-pulumi","content:en-us:blog:managing-gitlab-resources-with-pulumi.yml","Managing Gitlab Resources With Pulumi","en-us/blog/managing-gitlab-resources-with-pulumi.yml","en-us/blog/managing-gitlab-resources-with-pulumi",{"_path":2818,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2819,"content":2825,"config":2831,"_id":2833,"_type":14,"title":2834,"_source":16,"_file":2835,"_stem":2836,"_extension":19},"/en-us/blog/managing-multiple-environments-with-terraform-and-gitlab-ci",{"title":2820,"description":2821,"ogTitle":2820,"ogDescription":2821,"noIndex":6,"ogImage":2822,"ogUrl":2823,"ogSiteName":686,"ogType":687,"canonicalUrls":2823,"schema":2824},"Managing multiple environments with Terraform and GitLab CI","This tutorial shows how to set up and manage three different environments in one project using GitLab CI and Terraform.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663779/Blog/Hero%20Images/cicd-2018_blogimage.jpg","https://about.gitlab.com/blog/managing-multiple-environments-with-terraform-and-gitlab-ci","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Managing multiple environments with Terraform and GitLab CI\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sophia Manicor\"},{\"@type\":\"Person\",\"name\":\"Noah Ing\"}],\n        \"datePublished\": \"2023-06-14\",\n      }",{"title":2820,"description":2821,"authors":2826,"heroImage":2822,"date":2828,"body":2829,"category":694,"tags":2830},[2827,821],"Sophia Manicor","2023-06-14","\n\nUsing multiple environments ensures that your infrastructure as code (IaC) is rigorously tested before it is deployed. This tutorial will show a setup of how to manage **three different environments in one project** using GitLab CI and Terraform.\n\n## Prerequisites\n- Working knowledge of [GitLab CI/CD](https://docs.gitlab.com/ee/ci/introduction/index.html#continuous-integration)\n- An AWS / GCP account (where you will deploy to)\n- Working knowledge of Terraform\n- 5 minutes\n\n## Multiple environments\nIn this tutorial, we have three environments set up: dev, staging, and production.\n- Dev: This should be where all the experimental changes go. This environment is intended to develop new features and/or test out new changes.\n- Staging: After you have confirmed your changes in dev, this environment should have parity with the production environment.\n- Production: This environment has the latest versions of infrastructure and applications are live.\n\n## File structure\nFor each environment we set up a corresponding folder at the root level: folders are named dev, staging, and production respectively. Each folder stores all the Terraform infrastructure configuration for the corresponding environment. Within each of these folders, we created a CI file for that environment. \n\n## .gitlab-ci.yml\n\n### Environment-specific .gitlab-ci.yml\nThe file below is for the dev environment and is in the dev folder. Note that there is a rule with each job that only allows the jobs to run when a file in the dev folder is changed. There is a corresponding file in the staging and production folders that has the same rules to only allow jobs when those specific folders are changed. To keep each CI file running the same jobs we have made use of a helper file. \n\n[Environment-specific GitLab CI](https://gitlab.com/demos/infrastructure/terraform-multi-env/-/blob/main/dev/.gitlab-ci.yml)\n\n```yaml\ninclude:\n  - 'helper.yml'\n\nvariables:\n  TF_ROOT: ./dev  # The relative path to the root directory of the Terraform project\n  TF_STATE_NAME: default      # The name of the state file used by the GitLab-managed Terraform state backend\n  SECURE_ANALYZERS_PREFIX: \"$CI_TEMPLATE_REGISTRY_HOST/security-products\"\n  SAST_IMAGE_SUFFIX: \"\"\n  SAST_EXCLUDED_PATHS: \"spec, test, tests, tmp\"\n  PLAN: plan.cache\n  PLAN_JSON: plan.json\n\n\ncache:\n  key: \"${TF_ROOT}\"\n  paths:\n    - ${TF_ROOT}/.terraform/\n\nfmt-dev:\n  extends: .fmt\n  rules:\n      - changes:\n          - dev/**/*\n\nvalidate-dev:\n  extends: .validate\n  rules:\n      - changes:\n          - dev/**/*\n\nbuild-dev:\n  extends: .build\n  rules:\n      - changes:\n          - dev/**/*\n\nkics-iac-sast-dev:\n  extends: .kics-iac-sast\n  rules:\n      - changes:\n          - dev/**/*\n\ndeploy-dev:\n  extends: .deploy\n  rules:\n      - changes:\n          - dev/**/*\n\ndestroy-dev:\n  extends: .destroy\n  rules:\n      - changes:\n          - dev/**/*\n\n```\n\n### helper.yml\nThis helper file was created at the root level so that it could be referenced by all of the environment-specific files. The [helper.yml](https://gitlab.com/demos/infrastructure/terraform-multi-env/-/blob/main/helper.yml) is where all the heavy lifting is happening. This will make sure that all the jobs throughout the environment-specific file's configuration stays up to date and consistent. In the environment-specific files we 'included' the helper file and extended the jobs outlined below.\n\n```yaml\n\n.fmt:\n  stage: validate\n  script:\n    - cd \"${TF_ROOT}\"\n    - gitlab-terraform fmt\n  allow_failure: true\n\n\n.validate:\n  stage: validate\n  script:\n    - cd \"${TF_ROOT}\"\n    - gitlab-terraform validate\n\n\n.build:\n  stage: build\n  before_script:\n    - apk --no-cache add jq\n    - alias convert_report=\"jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\\\"create\\\":(map(select(.==\\\"create\\\"))|length),\\\"update\\\":(map(select(.==\\\"update\\\"))|length),\\\"delete\\\":(map(select(.==\\\"delete\\\"))|length)}'\"\n  script:\n    - cd \"${TF_ROOT}\"\n    - gitlab-terraform plan -out=$PLAN\n    - gitlab-terraform plan-json | convert_report > $PLAN_JSON\n  resource_group: ${TF_STATE_NAME}\n  artifacts:\n    paths:\n      - ${TF_ROOT}/plan.cache\n    reports:\n      terraform: ${TF_ROOT}/$PLAN_JSON\n\n.kics-iac-sast:\n  stage: test\n  artifacts:\n    reports:\n      sast: gl-sast-report.json\n  image:\n    name: \"$SAST_ANALYZER_IMAGE\"\n  variables:\n    SEARCH_MAX_DEPTH: 4\n    SAST_ANALYZER_IMAGE_TAG: 3\n    SAST_ANALYZER_IMAGE: \"$SECURE_ANALYZERS_PREFIX/kics:$SAST_ANALYZER_IMAGE_TAG$SAST_IMAGE_SUFFIX\"\n  allow_failure: true\n  script:\n    - /analyzer run\n\n\n.deploy:\n  stage: deploy\n  script:\n    - cd \"${TF_ROOT}\"\n    - gitlab-terraform apply\n  resource_group: ${TF_STATE_NAME}\n  when: manual\n  rules:\n      - changes:\n          - ${TF_ENVIRONMENT}/**/*\n\n.destroy:\n  stage: cleanup\n  script:\n    - cd \"${TF_ROOT}\"\n    - gitlab-terraform destroy\n  resource_group: ${TF_STATE_NAME}\n  when: manual\n\n```\n\n### Root-level .gitlab-ci.yml\n[Root-level GitLab CI](https://gitlab.com/demos/infrastructure/terraform-multi-env/-/blob/main/.gitlab-ci.yml)\n\nThe file that brings everything above together is the root-level CI file. This will be what the pipeline initially references when run. The [root-level GitLab CI](https://gitlab.com/demos/infrastructure/terraform-multi-env/-/blob/main/.gitlab-ci.yml) is where all of the stages and container images are defined. Note that they are inheriting `.gitlab-ci.yml` from each of the individual folders themselves.\n\n```yaml\ninclude:\n  - 'dev/.gitlab-ci.yml'\n  - 'staging/.gitlab-ci.yml'\n  - 'production/.gitlab-ci.yml'\n  \nimage:\n  name: \"$CI_TEMPLATE_REGISTRY_HOST/gitlab-org/terraform-images/releases/1.1:v0.43.0\"\n\nstages:          \n  - validate\n  - build\n  - test\n  - deploy\n  - cleanup\n\nvariables:\n  # If not using GitLab's HTTP backend, remove this line and specify TF_HTTP_* variables\n  TF_STATE_NAME: default\n  TF_CACHE_KEY: default\n\n```\n\n## Merge request + promotion through environments\nWith the project set up and GitLab CI’s triggering only based off changes to the individual environment folders, you can now safely promote changes using merge requests. When you want to make a change:\n1. First create a merge request in the dev environment with your *.tf files.\n2. Review the [Terraform integration in merge requests](https://docs.gitlab.com/ee/user/infrastructure/iac/mr_integration.html) to see X changes, X to Add, and X to Remove.\n3. If your changes are as expected, request your team members to review the changes and Terraform code.\n4. Apply the changes to your dev environment and merge in the merge request.\n5. If everything worked as intended, then make the same merge up into the staging environment.\n6. If the staging environment remains stable, make a merge request up into the production environment.\n\n\n## Results\nVoila, and there you have it! **A single project to manage three different infrastructure environments** in a safe way to ensure that your changes to production are tested, reviewed, and approved by the rest of your team members.\n\n",[1299,825,9,694],{"slug":2832,"featured":6,"template":698},"managing-multiple-environments-with-terraform-and-gitlab-ci","content:en-us:blog:managing-multiple-environments-with-terraform-and-gitlab-ci.yml","Managing Multiple Environments With Terraform And Gitlab Ci","en-us/blog/managing-multiple-environments-with-terraform-and-gitlab-ci.yml","en-us/blog/managing-multiple-environments-with-terraform-and-gitlab-ci",{"_path":2838,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2839,"content":2845,"config":2851,"_id":2853,"_type":14,"title":2854,"_source":16,"_file":2855,"_stem":2856,"_extension":19},"/en-us/blog/measuring-ai-effectiveness-beyond-developer-productivity-metrics",{"title":2840,"description":2841,"ogTitle":2840,"ogDescription":2841,"noIndex":6,"ogImage":2842,"ogUrl":2843,"ogSiteName":686,"ogType":687,"canonicalUrls":2843,"schema":2844},"Measuring AI effectiveness beyond developer productivity metrics ","AI assistants are here, yet measuring AI's impact on productivity isn’t figured out. Here’s why it’s a difficult problem and how GitLab is solving it.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749671994/Blog/Hero%20Images/AdobeStock_700757695.jpg","https://about.gitlab.com/blog/measuring-ai-effectiveness-beyond-developer-productivity-metrics","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Measuring AI effectiveness beyond developer productivity metrics \",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Taylor McCaslin\"}],\n        \"datePublished\": \"2024-02-20\",\n      }",{"title":2840,"description":2841,"authors":2846,"heroImage":2842,"date":2848,"body":2849,"category":781,"tags":2850},[2847],"Taylor McCaslin","2024-02-20","AI-powered productivity tools promise to boost productivity by automating repetitive coding and tedious tasks, as well as generating code. How organizations measure the AI impact of these productivity tools has yet to be truly figured out. GitLab is working on a solution: AI Impact is a dashboard grounded in [value stream analytics](https://about.gitlab.com/solutions/value-stream-management/) that will help organizations understand the effect of [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our AI-powered suite of features, on their productivity. AI Impact is the culmination of what we’ve learned at GitLab about measuring the impact of AI, and we wanted to share those lessons with you.\n\n[A report for The Pragmatic Engineer](https://newsletter.getdx.com/p/developer-productivity-metrics-at-top-companies) shows that measuring productivity in general isn’t straightforward, with top engineering teams around the globe all using different metrics. If everyone has a different productivity metric to optimize, how do we even begin to measure the impact of AI productivity tools? Welcome to why measuring AI assistant productivity impact is difficult and commonly misses the mark.\n\n>  Follow the progress of our AI Impact dashboard and [share your feedback](https://gitlab.com/groups/gitlab-org/-/epics/12978).\n\n## Flawed productivity metrics\n\nSimplistic productivity metrics like lines of code contributed per day or acceptance rates of AI suggestions fail to capture downstream costs. For instance, GitClear, according to [an Infoworld article](https://www.infoworld.com/article/3712685/is-ai-making-our-code-stupid.html), “analyzed 153 million lines of changed code between January 2020 and December 2023 and now expects that code churn ('the percentage of lines that are reverted or updated less than two weeks after being authored') will double in 2024.\" Thus, simply measuring lines of code risks technical debt pileup and skill atrophy in developers.  \n\n## Indirect impacts are hard to quantify\n\nThe goal of AI developer tools is to remove toil, allowing developers to focus on higher value tasks like system architecture and design. But how much time is really saved this way versus spent reviewing, testing, and maintaining AI-generated code? These second-order productivity impacts are very difficult to accurately attribute directly to AI, which may give you a false sense of value. One solution to this is to choose who gets to use AI productivity tools carefully.\n\n## Focus should be on business outcomes\n\nUltimately, what matters is real-world business outcomes, not developer activity metrics. Tracking lead time, cycle time, production defects, and user satisfaction better indicate where bottlenecks exist. If AI tools generate usable code faster, and quality teams can’t keep up with changes, the end software product may decrease in quality and lead to customer satisfaction problems. Shipping more sounds great until it causes problems that take even more time, money, and effort to resolve. Measuring business outcomes is also difficult and these measurements frequently are lagging indicators of problems. Measuring quality defects, security issues, and application performance are all ways to identify business impact sooner. \n\n## The need to balance speed and quality\n\nWhile AI code generation has the potential to accelerate development velocity, it should not come at the cost of overall quality and maintainability. Teams must strike the right balance between velocity and writing maintainable, well-tested code that solves actual business problems. Quality should not be sacrificed purely to maximize productivity metrics. This is when measuring lines of code AI generates or number of AI suggestions developers accept can optimize for the problematic outcomes. More code doesn't necessarily mean higher quality or productivity. More code means more to review, test, and maintain – potentially slowing delivery down.\n\nLet’s look at an example: AI-generated code output is scoped to the area a developer is currently working on. Current AI tools lack the ability to assess the broader architecture of the application (amplified in a microservices architecture). This means that even if the quality of the generated code is good, it may lead to repetition and code bloat because it will be inserted into the area targeted rather than making wider systematic changes. This is problematic in languages that are architected with object-oriented languages that use DRY (don't-repeat-yourself) principles. This is an active area of research and we’re excited to adopt new approaches and technologies to increase the context awareness of our AI features.\n\nAcceptance rate can be particularly misleading, and unfortunately is becoming the primary way AI productivity tools measure success. Developers may accept an AI-generated suggestion but then need to heavily edit or rewrite it. Thus, the initial acceptance gives no indication of whether the suggestion was actually useful. Acceptance rate is fundamentally a proxy for AI assistant quality, yet it is misconstrued as a productivity measure. This is especially misleading when all vendors are measuring acceptance rate differently and marketing based on this number. GitLab intentionally does not use this kind of data in our marketing. What we’ve seen in practice is that developers use AI-generated code similar to how an actor uses a cue – they look at the generated code and say, \"oh, right, that's the nudge I needed, I'll take it from here.\" \n\n## Implementation and team dynamics play a key role\n\nHow productivity gains materialize depends on how AI tools are implemented and developer dynamics. If some developers distrust the technology or reviews become lax expecting AI to catch errors, quality may suffer. Additionally, introducing AI tools often necessitates changes to processes like code reviews, testing, and documentation. Productivity could temporarily decline as teams adjust to new workflows before seeing gains. Organizations must ensure that when implementing AI tools, that they allow teams time to figure out how it works and how it fits into their workflows, knowing that this trial-and-error period may lead to reduced productivity metrics before seeing productivity gains. \n\nTo get this balance right, it’s important to define the tasks that are highly accurate and consistent and train the team to use AI for those use cases (at least, at first). We know that AI code generation is useful for producing scaffolding, test generation, and syntax corrections, as well as generating documentation. Have teams start there and they will see better results and learn to use the tool more effectively. Remember you can’t measure AI’s impact in a week. You have to give teams time to find their rhythm with their AI assistants. \n\n## Challenges exist, but AI is the future\n\nNow that we’ve talked about the challenges of measuring AI impact and potential risks, we do want to say at GitLab we do believe AI has a huge role to play in the evolution of DevSecOps platforms. That’s why we’re building GitLab Duo. But we are not rushing into productivity measurement by showing acceptance rates, or lines of code generated. We believe these are a step backwards to previous ways of thinking about productivity. Instead we’re looking at the data we have within our unified DevSecOps platform to present a more complete picture of AI Impact.  \n\n## What to measure instead\n\nMeasuring the productivity impacts of AI developer tools requires nuance and a focus on end-to-end outcomes rather than isolated productivity metrics. For these reasons, simple quantitative metrics tend to miss the nuances of measuring productivity with AI developer tools. The key is to combine quantitative data from across the software development lifecycle (SDLC) with qualitative feedback from developers on how AI actually impacts their day-to-day experience and shapes long-term development practices. Only then can we get an accurate picture of the productivity gains these tools can offer. We view AI as an augmentor to DevSecOps adoption, rather than a replacement for doing things the right way. Organizations focusing on building the right muscles in their SDLC practice are the ones best positioned to actually take advantage of any potential gains in developer coding productivity.\n\nSo what metric should we use instead? At GitLab we already have [value stream analytics](https://about.gitlab.com/solutions/value-stream-management/), which examine the end-to-end flow of work from idea to production to determine where bottlenecks exist. Value stream analytics isn’t a single measurement, it’s the ongoing tracking of metrics like lead time, cycle time, deployment frequency, and production defects. This keeps the focus on business outcomes rather than developer activity. By taking a holistic view across code quality, collaboration, downstream costs, and developer experience, teams can steer these technologies to augment (rather than replace) human abilities over the long run. \n\n## Introducing GitLab's AI Impact approach\n\nGitLab has the whole picture being a unified DevSecOps platform that spans the entire SDLC. We built [Value Stream Management](https://about.gitlab.com/solutions/value-stream-management/) to empower teams with metrics and insights to ship better software faster. Blending GitLab [Value Stream Analytics](https://about.gitlab.com/solutions/value-stream-management/) and [DORA metrics](https://about.gitlab.com/solutions/value-stream-management/dora/), and GitLab Duo usage data, we can provide organizations with the complete picture of how AI is impacting their SDLC. We’re calling this dashboard AI Impact, and it’s coming in an upcoming release to measure GitLab Duo’s impact on productivity. Follow our progress and [share your feedback](https://gitlab.com/groups/gitlab-org/-/epics/12978). \n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._",[717,496,9,848],{"slug":2852,"featured":91,"template":698},"measuring-ai-effectiveness-beyond-developer-productivity-metrics","content:en-us:blog:measuring-ai-effectiveness-beyond-developer-productivity-metrics.yml","Measuring Ai Effectiveness Beyond Developer Productivity Metrics","en-us/blog/measuring-ai-effectiveness-beyond-developer-productivity-metrics.yml","en-us/blog/measuring-ai-effectiveness-beyond-developer-productivity-metrics",{"_path":2858,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2859,"content":2865,"config":2869,"_id":2871,"_type":14,"title":2872,"_source":16,"_file":2873,"_stem":2874,"_extension":19},"/en-us/blog/medium-gitlab-saas-runners-on-linux-now-available-to-all-tiers",{"title":2860,"description":2861,"ogTitle":2860,"ogDescription":2861,"noIndex":6,"ogImage":2862,"ogUrl":2863,"ogSiteName":686,"ogType":687,"canonicalUrls":2863,"schema":2864},"Medium GitLab SaaS runners on Linux now available to all tiers","Free tier users can follow a few instructions to use medium SaaS runners on Linux to increase CI/CD pipleline speeds.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679838/Blog/Hero%20Images/fastlightrunner.jpg","https://about.gitlab.com/blog/medium-gitlab-saas-runners-on-linux-now-available-to-all-tiers","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Medium GitLab SaaS runners on Linux now available to all tiers\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Gabriel Engel\"}],\n        \"datePublished\": \"2023-08-01\",\n      }",{"title":2860,"description":2861,"authors":2866,"heroImage":2862,"date":2159,"body":2867,"category":994,"tags":2868},[1496],"\nFree tier users of GitLab can now experience shorter CI/CD execution times with medium GitLab [SaaS runners on Linux](https://docs.gitlab.com/ee/ci/runners/saas/linux_saas_runner.html). Previously, [Free tier](https://about.gitlab.com/pricing/) users could only use our small SaaS runner on Linux, which sometimes resulted in longer CI/CD execution times. As of now, though, our medium SaaS runners on Linux are available to all tiers.\n\nTo use the medium SaaS runners on Linux, simply add the `saas-linux-medium-amd64` tag in your project's `gitlab-ci.yml` file.\nUnder the hood, we spin up a fresh [GCP `n2d-standard-4`](https://cloud.google.com/compute/docs/general-purpose-machines#n2d_machine_types) VM for one-time use with 4 vCPUs, 16GB RAM, and 50GB storage attached.\n\nWe look forward to seeing our Free tier users increase their pipeline speeds.\n\n## References\n- [What are SaaS runners?](https://docs.gitlab.com/ee/ci/runners/)\n- [SaaS runners on Linux documentation](https://docs.gitlab.com/ee/ci/runners/saas/linux_saas_runner.html)\n- [Cost factor for SaaS runners](https://docs.gitlab.com/ee/ci/pipelines/cicd_minutes.html#additional-costs-on-gitlab-saas)\n",[109,9,994],{"slug":2870,"featured":6,"template":698},"medium-gitlab-saas-runners-on-linux-now-available-to-all-tiers","content:en-us:blog:medium-gitlab-saas-runners-on-linux-now-available-to-all-tiers.yml","Medium Gitlab Saas Runners On Linux Now Available To All Tiers","en-us/blog/medium-gitlab-saas-runners-on-linux-now-available-to-all-tiers.yml","en-us/blog/medium-gitlab-saas-runners-on-linux-now-available-to-all-tiers",{"_path":2876,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2877,"content":2883,"config":2888,"_id":2890,"_type":14,"title":2891,"_source":16,"_file":2892,"_stem":2893,"_extension":19},"/en-us/blog/meet-gitlab-duo-the-suite-of-ai-capabilities",{"title":2878,"description":2879,"ogTitle":2878,"ogDescription":2879,"noIndex":6,"ogImage":2880,"ogUrl":2881,"ogSiteName":686,"ogType":687,"canonicalUrls":2881,"schema":2882},"Meet GitLab Duo, the suite of AI capabilities powering your workflows","Learn about GitLab Duo, an expanding toolbox of features integrated directly into the GitLab platform to assist DevSecOps teams.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679194/Blog/Hero%20Images/duo-blog-post.png","https://about.gitlab.com/blog/meet-gitlab-duo-the-suite-of-ai-capabilities","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Meet GitLab Duo, the suite of AI capabilities powering your workflows\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David DeSanto, Chief Product Officer, GitLab\"}],\n        \"datePublished\": \"2023-06-22\",\n      }",{"title":2878,"description":2879,"authors":2884,"heroImage":2880,"date":2885,"body":2886,"category":781,"tags":2887},[1905],"2023-06-22","\nHave you ever wanted a real-time partner alongside you to help as you develop code, improve operations, and secure your software? [GitLab Duo](https://about.gitlab.com/gitlab-duo/), available now, is a powerful set of AI capabilities within GitLab’s DevSecOps Platform that does just that – suggesting code, explaining vulnerabilities, forecasting value streams, and much more.\n\nThe name GitLab Duo is rooted in You + GitLab AI = the AI dynamic duo. GitLab Duo goes beyond just being an AI pair programmer: It is an expanding toolbox of features integrated into the DevSecOps Platform to help teams across the entire software development environment become more efficient. GitLab Duo is your go-to for planning refinement, security risk resolution, CI/CD pipeline health, and analytics charting. \n\nGitLab Duo is a customer-centric approach focused on privacy first, where customers know their intellectual property is secured.\n\n## GitLab Duo capabilities\nGitLab Duo includes:\n\n- **Code Suggestions** helps developers create new code and update existing code, reducing cognitive load, improving efficiency, and allowing them to spend more time adding unique value to their applications.\n- **Explain this Code** uses AI to examine code, both within a merge request and in the repository view, and provides a natural language explanation, helping to enable all teams to understand the code being merged.\n- **Explain this Vulnerability** helps developers write more secure code by providing a natural language description of the vulnerability and the steps to resolve it.\n- **Generate detailed descriptions of epics, issues, and tasks** helps ensure all teams are aligned and can achieve their common goals faster.\n- **Summarize Issue Comments** helps get everyone up to speed quickly in epics, issues, and tasks.  \n- **Chat** enables users to ask configuration questions and receive natural language explanations, as well as links to GitLab Docs. \n\nThroughout the year, all the GitLab Duo capabilities will become available via GitLab Duo Chat. As humans, we gravitate towards conversational chat, which is why we expect GitLab Duo Chat to become a de facto choice for how users interact with GitLab AI capabilities. We will be adding new capabilities to GitLab Duo, including assisting users with generating planning descriptions, using natural language for CI configuration and chart generation, refactoring vulnerabilities from code, suggesting a fix for failed tests, helping resolve CI/CD pipeline failures, summarizing vulnerability reports, and assisting with merge request reviews.\n\nAt GitLab, we believe everyone can contribute. By bringing GitLab Duo capabilities to every persona who uses GitLab, everyone can benefit from AI-powered workflows and organizations can ship secure software faster.\n\n## The impact of GitLab Duo on workflow efficiency\nOur goal is to help you achieve a 10x improvement in workflow efficiency by tapping into all of the [DevSecOps Platform’s AI capabilities](https://about.gitlab.com/blog/ai-ml-in-devsecops-series/). With GitLab 16, business leaders get an enterprise-grade solution that delivers greater efficiency by reducing tool sprawl and gives teams greater visibility into their workflows.\n\nTo learn more about the exciting features and capabilities of GitLab Duo, [watch the replay of our GitLab 16 event](https://about.gitlab.com/sixteen/).\n\nStay tuned for more updates, and get ready to experience a new era of AI-powered DevSecOps workflows with [GitLab Duo](https://about.gitlab.com/gitlab-duo/).\n",[994,719,717,9],{"slug":2889,"featured":6,"template":698},"meet-gitlab-duo-the-suite-of-ai-capabilities","content:en-us:blog:meet-gitlab-duo-the-suite-of-ai-capabilities.yml","Meet Gitlab Duo The Suite Of Ai Capabilities","en-us/blog/meet-gitlab-duo-the-suite-of-ai-capabilities.yml","en-us/blog/meet-gitlab-duo-the-suite-of-ai-capabilities",{"_path":2895,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2896,"content":2902,"config":2907,"_id":2909,"_type":14,"title":2910,"_source":16,"_file":2911,"_stem":2912,"_extension":19},"/en-us/blog/meet-gitlab-duo-workflow-the-future-of-ai-driven-development",{"title":2897,"description":2898,"ogTitle":2897,"ogDescription":2898,"noIndex":6,"ogImage":2899,"ogUrl":2900,"ogSiteName":686,"ogType":687,"canonicalUrls":2900,"schema":2901},"Meet GitLab Duo Workflow - the future of AI-driven development","Workflow, our autonomous AI agent, will transform the way teams build and ship software – our first bold step towards AI-driven DevSecOps.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749658912/Blog/Hero%20Images/blog-image-template-1800x945__20_.png","https://about.gitlab.com/blog/meet-gitlab-duo-workflow-the-future-of-ai-driven-development","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Meet GitLab Duo Workflow - the future of AI-driven development\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David DeSanto, Chief Product Officer, GitLab\"}],\n        \"datePublished\": \"2024-06-27\",\n      }",{"title":2897,"description":2898,"authors":2903,"heroImage":2899,"date":2904,"body":2905,"category":781,"tags":2906},[1905],"2024-06-27","Imagine if software wrote itself. It seems like a distant future, but with ongoing advancements in large language models and GitLab’s unified AI-powered DevSecOps platform, that future is quickly coming into focus. During our [GitLab 17 launch event](https://about.gitlab.com/seventeen/), we announced GitLab Duo Workflow, an autonomous AI agent that will transform how teams build, secure, deploy, and monitor software.\n\nGitLab Duo Workflow moves beyond the current landscape of reactive, prompt-based AI assistants by creating an autonomous team member actively contributing to optimize every aspect of your software development lifecycle. Workflow distinguishes itself by leveraging GitLab’s unified data store, which seamlessly connects all relevant data, projects, repositories, and documentation. This allows Workflow to be an intelligent, always-on agent that constantly monitors your projects, anticipates potential production issues, automatically identifies and resolves vulnerabilities, optimizes your applications for peak performance, and streamlines onboarding by rapidly building customized remote development environments.\n\nAI is transforming how secure software is created, maintained, updated, deployed, and monitored, enabling organizations to ship more software than ever before. GitLab Duo Workflow represents our first bold step towards AI-driven DevSecOps. We aim to empower developers to focus on high-level problem-solving, innovation, and value creation, while [GitLab Duo](https://about.gitlab.com/gitlab-duo/) handles repetitive tasks and optimization behind the scenes.\n\n## The vision for GitLab Duo Workflow\nWith GitLab Duo Workflow, we are laser-focused on tackling several key use cases to automate and optimize the software development process from end to end.\n### 1. Development automated\n\nStraight from the IDE, GitLab Duo Workflow helps plan and prioritize tasks tailored to individual projects and defined organizational processes. Using the requirements from a particular work item (whether an epic, issue, or task), Workflow produces an implementation plan that developers can review and refine. Then, Workflow works through the plan, generating or rewriting code to accomplish and meet the defined requirements. Workflow accomplishes this by operating within a [GitLab Remote Development workspace](https://about.gitlab.com/blog/quick-start-guide-for-gitlab-workspaces/), allowing it to safely and securely evaluate, write, and test code changes. This also ensures that Workflow produces code that both meets the requirements as well as passes all CI pipeline tests, including security scans. If the pipeline fails, Workflow automatically addresses issues and troubleshoots as needed, ensuring only high-quality code that meets your organization's standards is created and committed to your projects.\n\nOnce ready, Workflow will automatically create a merge request outlining its code changes and go through your merge request approval processes, including engaging with the code reviewer or maintainer. You can even ask Workflow to review your code and have it comment on your merge requests just as a human code reviewer would today. Even better, Workflow will implement those suggestions for you if you'd like it to. And this is only the start.\n\n### 2. Intelligent continuous improvement\nGitLab Duo Workflow will analyze your codebase in real time, suggesting architectural optimizations for enhanced efficiency, performance, and cost savings. Furthermore, it will proactively identify opportunities for code refactoring to improve scalability and address technical debt by suggesting changes to developers or automatically implementing them in a sandbox environment. Additionally, Workflow will dynamically manage cloud resources to prevent overprovisioning and ensure your applications always meet their performance targets.\n\n### 3. Proactive security and compliance\nSecurity and compliance are top priorities for any organization. GitLab Duo Workflow will automatically ask developers to apply patches, refactor insecure code, and adapt to emerging threats in real time. Moreover, Workflow will continuously assess security risks associated with your applications and production environments and assist you with implementing mitigating controls.\n\n### 4. Self-optimizing performance\nGitLab Duo Workflow will incorporate sophisticated feedback loops for continuous learning and improvement. By analyzing data from monitoring tools, user interactions, and business outcomes, it will continuously refine its view of your codebase to ensure that your application architectures are always aligned with your business needs. As we see with all AI, Workflow will constantly improve, catching and fixing its own mistakes as it learns to be a partner in your organization.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://player.vimeo.com/video/967982166?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" frameborder=\"0\" allowfullscreen=\"true\" title=\"GitLab Duo Workflow the future of AI-driven DevSecOps\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## The future of AI is now\nGitLab Duo Workflow represents an exciting leap forward, transitioning from AI that requires constant human prompting to AI that drives development workflows and processes, seeking human guidance when needed. With GitLab's unified, AI-driven interface spanning the DevSecOps lifecycle, organizations will be able to create a new generation of AI-powered applications with unparalleled speed, efficiency, and innovation, all while maintaining the highest standards of security and compliance. No tradeoffs.\n\nStay tuned for more updates and insights as we continue to push the boundaries of what's possible with AI in software development. Together, let's embrace the future of AI-driven DevSecOps and unlock the full potential of your teams and organizations.\n\n> If you are curious about AI-driven DevSecOps and want to be part of this journey, including access to the pre-release program, please [sign up for our GitLab Duo Workflow waitlist](https://forms.gle/5ppRuNVb8LwSPNVJA).",[717,496,9,994,1016],{"slug":2908,"featured":91,"template":698},"meet-gitlab-duo-workflow-the-future-of-ai-driven-development","content:en-us:blog:meet-gitlab-duo-workflow-the-future-of-ai-driven-development.yml","Meet Gitlab Duo Workflow The Future Of Ai Driven Development","en-us/blog/meet-gitlab-duo-workflow-the-future-of-ai-driven-development.yml","en-us/blog/meet-gitlab-duo-workflow-the-future-of-ai-driven-development",{"_path":2914,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2915,"content":2921,"config":2926,"_id":2928,"_type":14,"title":2929,"_source":16,"_file":2930,"_stem":2931,"_extension":19},"/en-us/blog/meet-regulatory-standards-with-gitlab",{"title":2916,"description":2917,"ogTitle":2916,"ogDescription":2917,"noIndex":6,"ogImage":2918,"ogUrl":2919,"ogSiteName":686,"ogType":687,"canonicalUrls":2919,"schema":2920},"Meet regulatory standards with GitLab security and compliance","Compliance is more than one-off audits; it's a continuous process of managing risk by implementing guardrails and monitoring specific metrics. Learn how with this comprehensive guide.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098739/Blog/Hero%20Images/Blog/Hero%20Images/AdobeStock_282096522_securitycompliance.jpeg_1750098739024.jpg","https://about.gitlab.com/blog/meet-regulatory-standards-with-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Meet regulatory standards with GitLab security and compliance\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Abubakar Siddiq Ango\"}],\n        \"datePublished\": \"2023-08-17\",\n      }",{"title":2916,"description":2917,"authors":2922,"heroImage":2918,"date":2923,"body":2924,"category":694,"tags":2925,"updatedDate":2037},[1455],"2023-08-17","Guiding principles in the form of standards have consistently ensured the secure and reliable delivery of products and services to customers. \nThese standards, typically enforced by legally mandated organizations, regulate industries and prevent the spread of subpar products.\n\nIn the Information Technology (IT) sector, adhering to standards extends beyond the final product delivery; it encompasses the entire solution lifecycle. As every industry increasingly leverages various forms of technology to accelerate processes and boost efficiency, vast quantities of often sensitive data are generated, stored, and transmitted using IT tools and services. The improper handling of this data can cause severe consequences, potentially leading to financial losses in the [hundreds of millions of dollars](https://tech.co/news/data-breaches-updated-list).\n\nThis comprehensive guide explains global compliance standards and walks through how to meet regulatory standards with GitLab compliance and security policy management.\n\nArticle contents:\n\n- [Common IT compliance standards](#common-it-compliance-standards)\n- [Global and regional compliance standards](#global-and-regional-compliance-standards)\n    - [Country/regional regulations](#countryregional-regulations)\n    - [Industry-specific standards](#industry-specific-standards)\n- [Importance of continuous compliance](#importance-of-continuous-compliance)\n- [Regulatory compliance vs. self-imposed standards](#regulatory-compliance-vs.-self-imposed-standards)\n- [Compliance management](#compliance-management)\n- [Compliance management with GitLab](#compliance-management-with-gitlab)\n    - [Compliance frameworks and pipelines](#compliance-frameworks-and-pipelines)\n    - [Security policy management](#security-policy-management)\n        - [Scan execution policies](#scan-execution-policies)\n        - [Scan result policies](#scan-result-policies)\n        - [License approval policies](#license-approval-policies)\n    - [Audit management](#audit-management)\n        - [Preparing for audits](#preparing-for-audits)\n        - [Using GitLab audit logs effectively](#using-gitlab-audit-logs-effectively)\n        - [Audit events streaming](#audit-events-streaming)\n- [Best practices for compliance management](#best-practices-for-compliance-management)\n- [Learn more](#learn-more)\n\n## Common IT compliance standards\nRegulatory compliance standards take various forms and depend on the industry or region in which an organization operates. First, we will look at common compliance standards, followed by region and industry-specific standards.\n\n### HIPAA\n\nThe [Health Insurance Portability and Accountability Act (HIPAA)](https://www.hhs.gov/hipaa/index.html) is important legislation that has impacted the healthcare industry in the U.S. The main aim of HIPAA, passed in 1996, is to protect sensitive patient health information from being disclosed without the patient's consent or knowledge.\n\nIt is essential to safeguard patient privacy, ensure data security, and standardize electronic healthcare transactions. HIPAA has forced healthcare providers, insurers, and related entities to implement strict data protection measures, significantly reducing unauthorized access to medical records and enhancing patient trust.\n\n### GDPR\n\n[The General Data Protection Regulation (GDPR)](https://gdpr-info.eu/) is a significant European Union law that governs the protection of personal data. Implemented in 2018, GDPR establishes strict guidelines for organizations handling the personal information of EU residents. It grants individuals greater control over their data, including the right to access, rectify, and erase personal information held by companies. GDPR mandates that organizations obtain explicit consent before collecting or processing personal data and clearly explain the purpose of data collection. Non-compliance can result in substantial financial penalties.\n\nAlthough an EU regulation, GDPR has global implications, affecting any organization that processes EU residents' data. This legislation has prompted widespread changes in data handling practices and has heightened awareness of privacy issues worldwide.\n\n### NIST SSDF\n\nThe [NIST Secure Software Development Framework (SSDF)](https://csrc.nist.gov/Projects/ssdf) is a guide to help organizations make safer software. Created by the National Institute of Standards and Technology, it offers [basic practices for secure software development](https://about.gitlab.com/blog/comply-with-nist-secure-supply-chain-framework-with-gitlab/).\n\nThe SSDF focuses on four main areas: getting the organization ready, protecting the software, making well-secured software, and dealing with vulnerabilities. It helps companies think about security, including security protocols, during development and throughout the software supply chain.\n\nBy following these guidelines, organizations can create software with fewer weak points and handle problems more effectively. The SSDF is flexible and can work with different software development methods, making it useful for many organizations.\n\n### PCI DSS\n\nThe [Payment Card Industry Data Security Standard (PCI DSS)](https://www.pcisecuritystandards.org/) is a set of security rules for organizations that handle credit card information. Created by major credit card companies, it aims to protect cardholders' data and prevent fraud. PCI DSS requires businesses to build and maintain a secure network, protect cardholder data, use strong access control measures, regularly monitor and test networks, and maintain an information security policy. These rules apply to any company that accepts, processes, stores, or transmits credit card data.\n\nCompliance with PCI DSS is mandatory for these businesses, regardless of their size or transaction volume. By following these standards, companies can better safeguard sensitive financial information, reduce the risk of data breaches, and maintain customer trust. Regular audits ensure ongoing compliance with these important security measures.\n\n### ISO 27000\n\n[ISO/IEC 27000](https://www.iso.org/standard/iso-iec-27000-family) provides the foundational framework for the ISO/IEC 27000 family of standards, offering a comprehensive overview of information security management systems (ISMS). It establishes a standardized vocabulary by defining key terms and concepts, ensuring consistent understanding across organizations in the field of information security.\n\nThe standard outlines the core components and processes to establish and maintain an effective ISMS. This guidance enables organizations to systematically manage information security risks, protecting confidential data and intellectual property.\n\nAdherence to ISO/IEC 27000 allows organizations to build a robust ISMS, enhancing their resilience against cyber threats, safeguarding valuable information assets, and fostering stakeholder trust.\n\n> [Learn how GitLab can help you on your ISO 27001 compliance journey.](https://about.gitlab.com/blog/how-gitlab-can-support-your-iso-compliance-journey/)\n\n## Global and regional compliance standards\n\n### Country/regional regulations\n\nWhile compliance standards like HIPAA and GDPR are known globally, they are USA and EU standards respectively. They influence other regional standards around the globe but are only required for companies to adhere to where they handle data from, for example, the EU. Several countries have compliance standards that must be met if a company operates in such countries. Here are a few other country-specific standards:\n- [SOX](https://en.wikipedia.org/wiki/Sarbanes%E2%80%93Oxley_Act) (USA, Public companies): Sarbanes-Oxley Act. Mandates proper financial record-keeping and reporting for public companies.\n- [PIPEDA](https://www.priv.gc.ca/en/privacy-topics/privacy-laws-in-canada/the-personal-information-protection-and-electronic-documents-act-pipeda/) (Canada, Commercial businesses): Personal Information Protection and Electronic Documents Act. Governs how private sector organizations collect, use, and disclose personal information.\n- [PDPA](https://www.pdpc.gov.sg/overview-of-pdpa/the-legislation/personal-data-protection-act) (Singapore, All organizations): Personal Data Protection Act. Governs the collection, use, and disclosure of personal data by organizations.\n- [APPI](https://www.ppc.go.jp/files/pdf/Act_on_the_Protection_of_Personal_Information.pdf) (Japan, All industries): Act on the Protection of Personal Information. Regulates the use of personal information in Japan.\n- [LGPD](https://lgpd-brazil.info/) (Brazil, All industries): Lei Geral de Proteção de Dados. Brazil's data protection law is similar to GDPR.\n- [FISMA](https://www.cisa.gov/topics/cyber-threats-and-advisories/federal-information-security-modernization-act) (USA, Federal agencies): Federal Information Security Management Act. Defines a framework for managing information security for federal information systems.\n- [POPI Act](https://popia.co.za/) (South Africa, All sectors): The Protection of Personal Information Act promotes the protection of personal information processed by public and private bodies.\n- [PDPA](https://www.pwc.com/th/en/tax/personal-data-protection-act.html) (Thailand, All sectors): Personal Data Protection Act. Like GDPR, it regulates the collection, use, and disclosure of personal data in Thailand.\n- [PIPL](https://en.wikipedia.org/wiki/Personal_Information_Protection_Law_of_the_People%27s_Republic_of_China) (China, All sectors): Personal Information Protection Law. China's first comprehensive data protection law is similar to GDPR.\n- [NDPR](https://nitda.gov.ng/wp-content/uploads/2021/01/NDPR-Implementation-Framework.pdf) (Nigeria, All sectors): Nigeria Data Protection Regulation. Safeguards the rights of natural persons to data privacy. \n- [DIFC Data Protection Law](https://www.difc.ae/business/laws-and-regulations/legal-database/difc-laws/data-protection-law-difc-law-no-5-2020) (Dubai, Companies in Dubai International Financial Centre): Regulates the processing of personal data in the DIFC free zone.\n- [PDPA](https://www.pdp.gov.my/jpdpv2/laws-of-malaysia-pdpa/personal-data-protection-act-2010/?lang=en) (Malaysia, Commercial transactions): Personal Data Protection Act. Regulates the processing of personal data in commercial transactions.\n- [Privacy Act](https://www.ag.gov.au/rights-and-protections/privacy) (Australia, Government agencies, and some private sector organizations) regulates how personal information is handled by Australian government agencies and some private sector organizations.\n- [KVKK](https://www.kvkk.gov.tr/Icerik/6649/Personal-Data-Protection-Law) (Turkey, All sectors): Turkish Personal Data Protection Law. Regulates the processing of personal data and protects individual rights.\n\nThese standards reflect the growing global concern for data privacy and security. Many countries are developing their own frameworks inspired by established regulations like GDPR. Each standard is tailored to the specific legal, cultural, and economic context of its country.\n\n### Industry-specific standards\n\n- [PCI DSS](https://www.pcisecuritystandards.org/) (Financial Services): The Payment Card Industry Data Security Standard applies to all organizations that handle credit card information globally.\n- [ISO 27001](https://www.iso.org/standard/iso-iec-27000-family) (All industries) is an Information Security Management System standard that provides a framework for information security management practices.\n- [GAMP 5](https://qbdgroup.com/en/blog/gamp-categories/) (Pharmaceutical): Good Automated Manufacturing Practice. Guidelines for computerized systems in pharmaceutical manufacturing.\n- [ISO 13485](https://www.iso.org/standard/59752.html) (Medical Devices): Specifies requirements for a quality management system for medical device manufacturers.\n- [COBIT](https://www.isaca.org/resources/cobit) (IT Management): Control Objectives for Information and Related Technologies. Framework for IT management and IT governance.\n- [ITIL](https://en.wikipedia.org/wiki/ITIL) (IT Services) is an Information Technology Infrastructure Library, a set of detailed practices for IT service management.\n- [NIST CSF](https://www.nist.gov/cyberframework) (Cybersecurity): National Institute of Standards and Technology Cybersecurity Framework. Guidance on managing and reducing cybersecurity risk.\n- [WCAG](https://www.w3.org/WAI/standards-guidelines/wcag/) (Web Accessibility): The Web Content Accessibility Guidelines aim to make web content more accessible to people with disabilities.\n- [Basel III](https://www.bis.org/bcbs/basel3.htm) (Banking) is the international regulatory framework for banks, including IT risk management requirements.\n- [TISAX](https://portal.enx.com/en-US/TISAX/) (Automotive): Trusted Information Security Assessment Exchange. Information security assessment and exchange mechanism for the automotive industry. (Learn how [GitLab's TISAX certification](https://about.gitlab.com/blog/gitlab-drives-automotive-industry-information-security-with-tisax/) helps customers in the automotive industry.)\n\nThese standards apply across national boundaries to specific industries or aspects of IT, ensuring consistent practices and security measures globally within their respective domains.\n\n## Importance of continuous compliance\nOrganizations need to implement systems that ensure compliance with relevant regulatory requirements and can achieve this with continuous compliance. [Continuous software compliance](https://about.gitlab.com/solutions/compliance/) is essential to every industry, as it provides ongoing monitoring, assessment, and adjustment of an organization's systems, processes, and practices to ensure they consistently meet relevant standards and regulations.\n\nContinuous compliance is not just a regulatory checkbox but a strategic necessity for software development today. It empowers organizations to proactively navigate emerging threats, technological shifts, and regulatory changes while fostering stakeholder trust, operational efficiency, and competitive advantage in an increasingly complex business environment.\n\n## Regulatory compliance vs. self-imposed standards\n\nRegulatory compliance and self-imposed standards are two distinct approaches to organizational governance. Regulatory compliance involves adhering to mandatory laws and regulations set by external authorities, which have a broad scope and potential legal consequences for non-compliance. It focuses on meeting minimum legal requirements and is generally less flexible. Examples include GDPR, HIPAA, and SOX.\n\nIn contrast, self-imposed standards are voluntary guidelines adopted by organizations to improve quality, security, or performance. These can be tailored to specific needs, are highly adaptable, and typically aim to exceed minimum requirements. While failure to meet self-imposed standards may impact reputation, it usually doesn't have legal ramifications.\nThe key differences lie in their origin, motivation, adaptability, and scope. Many organizations implement both approaches to create a comprehensive quality, security, and performance management strategy.\n\n## Compliance management\n\nTo meet standards, organizations must evaluate the right [compliance metrics](https://advisory.kpmg.us/articles/2018/compliance-metrics.html) and integrate them into their standard operating procedures to provide insights that enable early detection and prevention of current and future compliance risks. Thus, there is a need for efficient [compliance management](https://about.gitlab.com/solutions/compliance/). Compliance management goes beyond checking off a checklist periodically; it's a comprehensive organization-wide continuous process.\n\n## Compliance management with GitLab\n\nGitLab provides features that allow organizations to create [compliance frameworks](https://docs.gitlab.com/ee/user/group/compliance_frameworks.html), [security policies](https://docs.gitlab.com/ee/user/application_security/policies/), and [audit management](https://docs.gitlab.com/ee/administration/audit_reports.html). GitLab also enables compliance or leadership teams to monitor compliance metrics with [compliance reports](https://docs.gitlab.com/ee/user/compliance/compliance_report/index.html). Let's take a look at some of these features.\n\n### Compliance frameworks and pipelines\n\nOrganizations can create a [compliance framework](https://docs.gitlab.com/ee/user/group/compliance_frameworks.html) that identifies projects in GitLab that must meet defined compliance requirements, which can be enforced with [compliance pipelines](https://docs.gitlab.com/ee/user/group/compliance_pipelines.html). For example, a FinTech company can create a [default compliance framework](https://docs.gitlab.com/ee/user/group/compliance_frameworks.html#default-compliance-frameworks) for all projects, ensuring every stage of their software development lifecycle meets the PCI DSS requirements for handling cardholder data.\n\nThese requirements are then enforced by ensuring every change introduced to the codebase is sufficiently tested automatically with GitLab's [application security features](https://docs.gitlab.com/ee/user/application_security/), which cover source code, dependencies, licenses, vulnerabilities in running application and infrastructure configurations. You can learn more about how GitLab helps you achieve PCI compliance and other [regulatory compliance](https://about.gitlab.com/solutions/continuous-software-compliance/) with compliance frameworks.\n\nThe following videos demonstrate setting up and using compliance frameworks and pipelines.\n\n**Video tutorial: Create compliance frameworks**\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/IDswzRI-8VQ\" title=\"How to setup Compliance Frameworks &amp; Pipelines in GitLab\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n**Video tutorial: Enforce compliance pipelines**\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/jKA_e_jimoI\" title=\"GitLab Compliance Pipelines &amp; Overriding Settings\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n### Security policy management\n\nSecurity and compliance teams can use GitLab to enforce compliance requirements by ensuring security scanners run in certain pipelines or require approval on merge requests when [security policies](https://docs.gitlab.com/ee/user/application_security/policies/) are violated. GitLab supports [scan execution](https://docs.gitlab.com/ee/user/application_security/policies/scan-execution-policies.html) and [scan result](https://docs.gitlab.com/ee/user/application_security/policies/scan-result-policies.html) policies. These policies are defined in a dedicated [security policy project](https://docs.gitlab.com/ee/user/application_security/policies/#security-policy-project) that separates duties between security and development teams. Security policies can be applied granularly at the group, sub-group, and project levels. The policies can be edited in rule mode, which uses the [policy editor](https://docs.gitlab.com/ee/user/application_security/policies/#policy-editor), or by yaml mode.\n\n#### Scan execution policies\nScan execution policies can be configured to run on a specified [GitLab Runner](https://docs.gitlab.com/runner/), including the following:\n-  [Static Application Security Testing](https://docs.gitlab.com/ee/user/application_security/sast/)\n- [Infrastructure as \nCode](https://docs.gitlab.com/ee/user/application_security/iac_scanning/)\n- [Dynamic Application Security Testing](https://docs.gitlab.com/ee/user/application_security/dast/)\n- [Secret Detection](https://docs.gitlab.com/ee/user/application_security/secret_detection/)\n- [Container Scanning](https://docs.gitlab.com/ee/user/application_security/container_scanning/)\n- [Dependency Scanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/) \n\nThe scan jobs can be run on schedule or anytime a pipeline runs. Compliance and security teams can use scan execution policies to periodically check on and proactively prevent vulnerability escalation as part of a vulnerability management strategy. They can also reinforce controls when new trends are observed from scan results.\n\n**Video tutorial: Set up security scan policies in GitLab**\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/ZBcqGmEwORA\" title=\"How to set up security scan policies in GitLab\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n#### Scan result policies\n\nScan result policies add required review and approval for merge requests when the results of specified security scans violate the policies' rules. For example, a policy can require a security team member to take action when a newly identified critical SAST vulnerability is detected. This way, security and compliance team members can support developers while ensuring the changes introduced to the codebase are secure and meet compliance requirements.\n\n**Video tutorial: Overview of GitLab Scan Result Policies**\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/w5I9gcUgr9U\" title=\"Overview of GitLab Scan Result Policies\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n#### License approval policies\nWhen selecting scan types for scan result policy rules, you can choose between security scan, the default behavior for scan result policies, and license scan, which helps ensure license compliance. License scanning depends on the output of the [dependency scanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/) [CI/CD](https://about.gitlab.com/topics/ci-cd/) job to check if identified licenses match specified criteria, then adds approval requirements before an open merge request can be merged. This is crucial to ensure that only dependencies with approved licenses are used in your organization.\n\n**Video demo: License approval policies**\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/34qBQ9t8qO8\" title=\"License Approval Policies Demo\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n### Audit management\n#### Preparing for audits \nAudits are essential for compliance management because they allow you to understand your organization's security and compliance posture. External audits required by regulators are often detailed and exhaustive. To prepare for them, organizations need to:\n- Determine which regulations or standards will be assessed and what areas of the organization will be examined.\n- Analyze past audit results and ensure any previously identified issues have been addressed.\n- Collect all relevant policies, procedures, and records that demonstrate compliance.\n- Before the official audit, an internal audit must be performed to identify and address any potential compliance gaps.\n- Brief employees on the audit process and their roles. Conduct training if necessary.\n- Ensure all required documentation is easily accessible and well-organized.\n- Ensure all compliance-related policies and procedures are up-to-date and aligned with current regulations.\n- Verify that all technical safeguards and controls are in place and functioning correctly.\n- Identify key personnel who may be interviewed and brief them on potential questions.\n- Address known issues: If any known compliance issues exist, develop and document plans to address them.\n\nTo enable your preparedness, GitLab features: [Audit Events](https://docs.gitlab.com/ee/administration/audit_events.html) and [Compliance Center](https://docs.gitlab.com/ee/user/compliance/compliance_center/index.html) give a detailed view of an organization's compliance.\n\n#### Using GitLab audit logs effectively \n\nYou want to know every action taken on the GitLab instance with [audit events](https://docs.gitlab.com/ee/administration/audit_events.html). Audit reports allow you to track every significant event, who performed it, and when. You can also generate detailed reports from audit events using [audit reports](https://docs.gitlab.com/ee/administration/audit_reports.html), allowing you to prove your compliance to auditors or regulators.\n\n![Audit events](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098755/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098755493.png)\n\n[The compliance center](https://docs.gitlab.com/ee/user/compliance/compliance_report/index.html#compliance-violations-report) is a significant component of audit management in GitLab, giving visibility to your organization's compliance posture. Compliance reports detail every violation discovered with the [compliance violations report](https://docs.gitlab.com/ee/user/compliance/compliance_center/compliance_violations_report.html) and the frameworks used by projects within your organization with the compliance [frameworks report](https://docs.gitlab.com/ee/user/compliance/compliance_center/compliance_frameworks_report.html).\n\n![Meet regulatory requirements - image 2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098756/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098755493.png)\n\n\u003Ccenter>\u003Ci>Example of a compliance violations report from a parent GitLab group.\u003C/i>\u003C/center>\n\n![Meet regulatory requirements - image 3](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098755/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750098755495.png)\n\n\u003Ccenter>\u003Ci>Example of a compliance framework report for all projects in a group\u003C/i>\u003C/center>\n\n#### Audit events streaming\nMost organizations have existing systems to monitor activities in their systems in real-time. With [audit events streaming](https://docs.gitlab.com/ee/administration/audit_event_streaming/index.html) on GitLab, you can integrate third-party solutions like Splunk infrastructure monitoring or DataDog streams monitoring service for real-time audit events analytics. All audit events data are sent to the streaming destination (it's essential to stream to a trusted service). Audit events streaming can be [configured at top-level groups](https://docs.gitlab.com/ee/administration/audit_event_streaming/index.html#top-level-group-streaming-destinations) and at the [instance level](https://docs.gitlab.com/ee/administration/audit_event_streaming/#instance-streaming-destinations) for self-managed GitLab instances.\n\n## Best practices for compliance management \n\nHere are some best practices for effective compliance management:\n- Establish a strong compliance culture that promotes organizational compliance awareness and ensures leadership commitment and support.\n- Develop a comprehensive compliance program with clear policies and procedures and regularly review the program to reflect regulation changes.\n- Implement risk assessment and management to regularly identify and assess compliance risks, prioritizing risks based on potential impact and likelihood.\n- Conduct regular compliance training tailored to specific roles and responsibilities for all employees.\n- Implement compliance management to automate compliance monitoring and compliance reporting where possible.\n- Perform internal audits to identify gaps and areas for improvement. It is also essential to consider external audits unbiasedly and use audit results to refine and improve compliance processes.\n- Stay informed about regulatory changes by assigning responsibility for monitoring regulatory updates and participating in industry associations and forums.\n- Integrate compliance into business processes, embed compliance checks into operational workflows, and consider compliance implications in strategic decision-making. Align compliance goals with business objectives\n- Develop response plans for potential compliance breaches and conduct mock scenarios to test readiness for incidents and violations.\n\n## Learn more\nCompliance is a continuous process of efficiently managing risk by implementing guardrails and monitoring compliance metrics. GitLab empowers organizations to fulfill regulatory standards with our [compliance management](https://about.gitlab.com/solutions/compliance/) features. With GitLab, you can improve the software supply chain experience, build more secure software faster, and maintain the trust of your users, clients, and community.\n\n> Learn more about compliance and security policy management with the [GitLab DevSecOps tutorial](https://gitlab-da.gitlab.io/tutorials/security-and-governance/devsecops/simply-vulnerable-notes/), which contains lessons covering the complete application security lifecycle in GitLab.\n\n## Read more\n- [Introducing GitLab Dedicated for Government](https://about.gitlab.com/blog/introducing-gitlab-dedicated-for-government/)\n- [How to ensure separation of duties and enforce compliance with GitLab](https://about.gitlab.com/blog/ensuring-compliance/)\n- [The ultimate guide to least privilege access with GitLab](https://about.gitlab.com/blog/the-ultimate-guide-to-least-privilege-access-with-gitlab/)",[9,496,694,186],{"slug":2927,"featured":6,"template":698},"meet-regulatory-standards-with-gitlab","content:en-us:blog:meet-regulatory-standards-with-gitlab.yml","Meet Regulatory Standards With Gitlab","en-us/blog/meet-regulatory-standards-with-gitlab.yml","en-us/blog/meet-regulatory-standards-with-gitlab",{"_path":2933,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2934,"content":2940,"config":2945,"_id":2947,"_type":14,"title":2948,"_source":16,"_file":2949,"_stem":2950,"_extension":19},"/en-us/blog/memory-safe-vs-unsafe",{"title":2935,"description":2936,"ogTitle":2935,"ogDescription":2936,"noIndex":6,"ogImage":2937,"ogUrl":2938,"ogSiteName":686,"ogType":687,"canonicalUrls":2938,"schema":2939},"How to secure memory-safe vs. manually managed languages","Learn how GitLab reduces source code risk using scanning, vulnerability management, and other key features.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749672878/Blog/Hero%20Images/securityscreen.jpg","https://about.gitlab.com/blog/memory-safe-vs-unsafe","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to secure memory-safe vs. manually managed languages\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Fernando Diaz\"}],\n        \"datePublished\": \"2023-03-14\",\n      }",{"title":2935,"description":2936,"authors":2941,"heroImage":2937,"date":2942,"body":2943,"category":694,"tags":2944},[1533],"2023-03-14","The National Security Agency (NSA) has published an executive summary\nshowcasing the \n\nrisk of using [manually managed\nlanguages](https://en.wikipedia.org/wiki/Manual_memory_management) over\n[memory-safe\nlanguages](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science))\nin application\n\ndevelopment. Manual memory management may introduce major bugs and security\nrisks into your application if\n\nthe memory is managed incorrectly.\n\n\nSecurity bugs introduced by manually managed languages can be catastrophic\nto the function of the\n\napplication, as well as the information contained in the application. These\nbugs may cause\n\nperformance slowdowns, application crashes, remote code execution,\ninformation leakage, and\n\nsystem failures.\n\n\nBugs that may be introduced include the following:\n\n\n* [Memory leak](https://en.wikipedia.org/wiki/Memory_leak): Memory no longer\nbeing used is not released, which reduces the amount of available memory.\n\n* [Buffer overflow](https://en.wikipedia.org/wiki/Buffer_overflow):\nOverwriting of memory locations adjacent to a buffers boundary.\n\n* [Segmentation fault](https://en.wikipedia.org/wiki/Segmentation_fault): An\napplication tries to access a restricted piece of memory.\n\n* [Wild pointers](https://en.wikipedia.org/wiki/Dangling_pointer): Pointer\npoints to the memory which has been deallocated.\n\n* [Undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior): An\napplication with unpredictable behavior.\n\n\nTo provide some insight on the prevalance of risk introduced by manually\nmanaged languages, Microsoft\n\nrevealed that within the span of 12 years, [70% of their\nvulnerabilities](https://github.com/Microsoft/MSRC-Security-Research/blob/master/presentations/2019_02_BlueHatIL/2019_01%20-%20BlueHatIL%20-%20Trends%2C%20challenge%2C%20and%20shifts%20in%20software%20vulnerability%20mitigation.pdf)\nwere due to mismanagement of memory.\n\nGoogle reported that there was a [similar percentage of\nvulnerabilities](https://security.googleblog.com/2021/09/an-update-on-memory-safety-in-chrome.html)\nintroduced by memory safety\n\nviolations within the Chrome browser.\n\n\nAll these vulnerabilities can be exploited by malicious actors who may\ncompromise a device, potentially leading to a compromise of a larger network\ninfrastructure. With this large risk presented by mismanaged memory,\n\nthe NSA advises organizations to consider using memory-safe languages\nwherever possible and providing\n\nmechanisms to harden applications built with manually managed languages.\n\n\n## Memory-safe languages vs. manually managed languages\n\n\nA memory-safe language is a language where memory allocation and garbage\ncollection are abstracted away from\n\nthe developer and handled by the programming language itself. These\nlanguages include **Python**, **Java**, and **Go**,\n\nto name a few.\n\n\nIn contrast, manually managed languages provide a developer with full\ncontrol over the system memory (with some exceptions).\n\nThe most popular manually managed languages are **C** and **C++**.\n\n\nEach language type has a purpose and use case. There are times when a\nmemory-safe language is recommended, but there are also\n\ntimes when it may not suit the application requirements.\n\n\nBelow is a list of some pros and cons of each language type:\n\n\n| Language type | Pros | Cons |\n\n| ------------- | ---- | ---- |\n\n| Memory safe | Memory mangement abstracted from developer, reduced risk of\nmemory errors | Reduced efficency/performance, unpredictable garbage\ncollection |\n\n| Manually managed | Enhanced efficency/performance, no garbage collection\noverhead | Prone to memory-related failures |\n\n\nManually managed languages provide the developer with more power, but also\nintroduce a greater amount\n\nof risk, so they should only be used where required.\n\n\n## Memory 'unsafe' language security scanning\n\n\nAlthough many organizations are promoting the use of memory-safe languages\nvs. manually managed ones, it is unrealistic\n\nto remove manually managed languages from a developer's toolbox. Therefore,\ndevelopers must get ahead of all the\n\nbugs/vulnerabilities that may be introduced. This can be done by scanning\napplication source code.\n\n\nGitLab supports various scanners for memory-unsafe languages. Below you can\nsee the scanners\n\nused for C and C++:\n\n\n| Language | Scanners |\n\n| -------- | -------- |\n\n| C | [Semgrep with GitLab-managed\nrules](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep) |\n\n| C++ |\n[Flawfinder](https://gitlab.com/gitlab-org/security-products/analyzers/flawfinder)\n|\n\n\nNow let's take a look at how [GitLab's static application security testing\n(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) allows\nus to find and resolve vulnerabilities.\n\nBelow is an application which doesn't crash, but may generate unexpected\nbehavior:\n\n\n```C\n\n#include \u003Cstdio.h>\n\n\nint main()\n\n{  \n  char msg[5] = \"Hello\";\n\n  /* Add exclamation, to a position that doesn't exist*/\n  msg[8] = '!';\n\n  /* print each letter 1 by 1 */\n  /* Notice we are going further than the length of the array */\n  int i;\n  for (i = 0; i \u003C 10; ++i)\n  {\n    printf(\"%i: %c \\n\", i, msg[i]);\n  }\n\n  return 0;\n}\n\n```\n\n\nWhen running the GitLab SAST scanner, the vulnerability is detected and a\nsolution is provided:\n\n\n![GitLab SAST scanner\nresults](https://about.gitlab.com/images/blogimages/memory-safe-vs-manually-managed/CWE_120.png)\n\n\nIt shows you need to **perform bounds checking, use functions that limit\nlength**, or\n\n**ensure that the size is larger than the maximum possible length.** You can\nalso see the\n\n[CWE](https://cwe.mitre.org/data/definitions/120.html) for more information\non how the system may be impacted.\n\nNote that vulnerabilities are actionable. These actions include the ability\nto dismiss a vulnerability and add\n\nadditional information for the security team to review, or a confidential\nissue can be created for review.\n\n\nThese scanners allow [DevSecOps](/topics/devsecops/) teams to resolve\nsecurity issues before code makes it into production and safeguard their\napplication\n\nfrom memory issues. Note that not all memory issues are easily detected due\nto the nature of manual memory management.\n\nTherefore, it is also important to add unit tests, fuzzing, and run checks\nusing the GitLab CI to further ensure the reliability\n\nand security of your application.\n\n\nThe following applications contain examples of creating a GitLab pipeline\nfor C applications:\n\n- [General Build, SAST, and\nRun](https://gitlab.com/tech-marketing/devsecops/initech/other/cul8r)\n\n- [Coverage-based\nfuzzing](https://gitlab.com/gitlab-org/security-products/demos/coverage-fuzzing/c-cpp-fuzzing-example)\n\n\n## Memory-safe language security scanning\n\n\nAs more developers move to memory-safe languages, it is important that the\ntools\n\nused to prevent vulnerabilities support these languages as well. GitLab\nprovides a rich feature set for\n\nsecuring application source code, especially for memory-safe languages.\n\n\nBelow is a table of some the popular languages GitLab supports. To see the\nfull list, visit the\n\n[GitLab SAST Language/Framework\nSupport](https://docs.gitlab.com/ee/user/application_security/sast/#supported-languages-and-frameworks)\npage.\n\n\n| Language | Scanners |\n\n| -------- | -------- |\n\n| Python | [Semgrep with GitLab-managed\nrules](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep),\n[Bandit](https://gitlab.com/gitlab-org/security-products/analyzers/bandit) |\n\n| Go | [Semgrep with GitLab-managed\nrules](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep),\n[GoSec](https://gitlab.com/gitlab-org/security-products/analyzers/gosec) |\n\n| Java | [Semgrep with GitLab-managed\nrules](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep),\n[SpotBugs with the find-sec-bugs\nplugin](https://gitlab.com/gitlab-org/security-products/analyzers/spotbugs),\n[MobSF\n(beta)](https://gitlab.com/gitlab-org/security-products/analyzers/mobsf) |\n\n| JavaScript | [Semgrep with GitLab-managed\nrules](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep),\n[ESLint security\nplugin](https://gitlab.com/gitlab-org/security-products/analyzers/eslint) |\n\n| Ruby |\n[brakeman](https://gitlab.com/gitlab-org/security-products/analyzers/brakeman)\n|\n\n\nGitLab uses a mix of open source tools developed in-house as well as\ncommonly used tools within the open source community.\n\nIt is important to note that GitLab's security research team creates custom\nrules to better reduce false positives as well\n\nas enhance the number of vulnerabilities found.\n\n\nHere are some Python functions, which can be exploited and then data can be\nobtained via [SQL\ninjection](https://owasp.org/www-community/attacks/SQL_Injection):\n\n\n```python\n\ndef select_note_by_id(conn, id=None, admin=False):\n   query = \"SELECT id, data FROM notes WHERE secret IS FALSE\"\n   cur = conn.cursor()\n\n   # Admin doesn't have search by id function, since only used in the UI\n   if admin:\n       query = \"SELECT id, data, ipaddress, hostname, secret FROM notes\"\n\n   if id:\n       if admin:\n           query = query + \" WHERE id = %s\" % id\n       else:\n           # NOTE: Vulnerable to SQL injection, can get secret notes\n           # by adding 'OR 1=1', since not parameterized\n           query = query + \" AND id = %s\" % id\n\n   try:\n       cur.execute(query)\n   except Exception as e:\n       note.logger.error(\"Error: cannot select note by id - %s\" % e)\n\n   allItems = cur.fetchall()\n   conn.close()\n\n   if len(allItems) == 0:\n       return []\n\n   return allItems\n```\n\n\nWhen running the GitLab SAST scanner, you can see the SQL injection\nvulnerability is detected. A solution\n\nis provided with the line of code affected as well as identifiers that\nprovide more information on how the\n\n[CWE](https://cwe.mitre.org/data/definitions/89.html) can affect your\nsystem.\n\n\n![SQL Injection and\nsolution](https://about.gitlab.com/images/blogimages/memory-safe-vs-manually-managed/CWE_89.png)\n\n\nNotice that there is also training to enable developers to understand the\nvulnerability and how\n\nit can be exploited, and to make them more security-aware.\n\n\n## Other application attack vectors\n\n\nUsing a memory-safe language along with a SAST scanner reduces vulnerability\nrisk, but there are more attack vectors to consider, including\nconfigurations, infrastructure, and dependencies. This is why it is\nimportant to scan all aspects of your application.\n\n\nGitLab offers the following scanners to help you achieve full coverage:\n\n\n| Scanner type | Description |\n\n| ------------ | ----------- |\n\n| [Dynamic application security testing\n(DAST)](https://docs.gitlab.com/ee/user/application_security/dast/) |\nExamines applications for vulnerabilities like these in deployed\nenvironments. |\n\n| [Infrastructure as code (IaC)\nscanning](https://docs.gitlab.com/ee/user/application_security/iac_scanning/)\n| Scans your IaC (Terraform, Ansible, AWS CloudFormation, Kubernetes, etc.)\nconfiguration files for known vulnerabilities. |\n\n| [Dependency\nscanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/)\n| Finds security vulnerabilities in your software dependencies. |\n\n| [Container\nscanning](https://docs.gitlab.com/ee/user/application_security/container_scanning/)\n| Scans your applications container images for known vulnerabilities. |\n\n| [License scanning -\nCycloneDX](https://docs.gitlab.com/ee/user/compliance/license_scanning_of_cyclonedx_files/index.html)\n| Capable of parsing and identifying over 500 different types of licenses\nand can extract license information from packages that are dual-licensed or\nhave multiple different licenses that apply. |\n\n| [Secret\ndetection](https://docs.gitlab.com/ee/user/application_security/secret_detection/)\n| Scans your repository for secrets. |\n\n| [Coverage-guided\nfuzzing](https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing/)\n| Sends random inputs to an instrumented version of your application in an\neffort to cause unexpected behavior. |\n\n| [Web API\nfuzzing](https://docs.gitlab.com/ee/user/application_security/api_fuzzing/)\n| Sets operation parameters to unexpected values in an effort to cause\nunexpected behavior and errors in the API backend. |\n\n\nAside from full scanner coverage, it important to add guardrails to prevent\nvulnerable code from compromising a production environment.\n\nThis can be done by requiring approval from the security team for merging\nany code with vulnerabilities using [GitLab\npolicies](https://docs.gitlab.com/ee/user/application_security/policies/).\n\n\nTo get started using these tools and more, check out the [GitLab Application\nSecurity](https://docs.gitlab.com/ee/user/application_security/) page.\n\nIt's as simple as signing up for GitLab Ultimate and adding some templates\nto your .gitlab-ci.yml.\n\n\n## Managing vulnerabilities of all types\n\n\nAlthough we can find and address vulnerabilities before they make it into\nproduction, it is not possible to\n\neliminate all risk. This is why it is important to be able to assess the\nsecurity posture of your project or\n\ngroup of projects.\n\n\nFor this, GitLab provides [Vulnerability\nReports](https://docs.gitlab.com/ee/user/application_security/vulnerability_report/),\nwhich allow you to manage and triage vulnerabilities\n\nwithin the main branch of the application. You can sort through all the\nvulnerabilities for a project or\n\ngroup of projects using a variety of different criteria.\n\n\n![Vulnerability report\nscreenshot](https://about.gitlab.com/images/blogimages/memory-safe-vs-manually-managed/vulnerability_report.png)\n\n\nClicking on a vulnerability sends you to its [Vulnerability\nPage](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/).\n\nThere you can review details on the vulnerability, manage its status,\ncollaborate with other members of\n\nthe security team, as well as create confidential issues to assign to\ndevelopers.\n\n\n![Vulnerability\nPage](https://about.gitlab.com/images/blogimages/memory-safe-vs-manually-managed/vulnerability_page.png)\n\n\n---\n\n\nThanks for reading! To learn more about available Security features, check\nout GitLab's [application security\ndocumentation](https://docs.gitlab.com/ee/user/application_security/)\n\nand get started securing your application today. You can also sign up for a\n[free GitLab Ultimate trial](https://about.gitlab.com/free-trial/)\n\nand test the [Simple Notes\nApplication](https://gitlab.com/tech-marketing/devsecops/initech/simple-notes),\nwhich contains a [full\ntutorial](https://tech-marketing.gitlab.io/devsecops/initech/simple-notes/)\non getting started\n\nwith implementing and using many of GitLab's security features.\n\n\n## References\n\n\nBelow are some references used in this blog:\n\n\n* [The Federal Government is Moving on Memory Safety for\nCybersecurity](https://www.nextgov.com/cybersecurity/2022/12/federal-government-moving-memory-safety-cybersecurity/381275/)\n\n* [Future of Memory Safety - Challenges and\nRecommendations](https://advocacy.consumerreports.org/wp-content/uploads/2023/01/Memory-Safety-Convening-Report-1-1.pdf)\n\n* [NSA Software Memory Safety\nReport](https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI_SOFTWARE_MEMORY_SAFETY.PDF)\n\n* [Memory Safety Wiki](https://en.wikipedia.org/wiki/Memory_safety)\n\n* [Manual Memory Management\nWiki](https://en.wikipedia.org/wiki/Manual_memory_management)\n\n* [Unsafe Languages - University of Washington CS Lecture\nNotes](https://courses.cs.washington.edu/courses/cse341/04wi/lectures/26-unsafe-languages.html)\n\n* [GitLab SAST](https://docs.gitlab.com/ee/user/application_security/sast/)\n\n* [GitLab Application\nSecurity](https://docs.gitlab.com/ee/user/application_security/)\n\n* [GitLab Vulnerability\nReports](https://docs.gitlab.com/ee/user/application_security/vulnerability_report/)\n\n\n_Cover image by [Mohammad\nRahmani](https://unsplash.com/@afgprogrammer?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\non\n[Unsplash](https://unsplash.com/s/photos/C-programming?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)_\n",[694,9,827],{"slug":2946,"featured":6,"template":698},"memory-safe-vs-unsafe","content:en-us:blog:memory-safe-vs-unsafe.yml","Memory Safe Vs Unsafe","en-us/blog/memory-safe-vs-unsafe.yml","en-us/blog/memory-safe-vs-unsafe",{"_path":2952,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2953,"content":2958,"config":2963,"_id":2965,"_type":14,"title":2966,"_source":16,"_file":2967,"_stem":2968,"_extension":19},"/en-us/blog/merge-request-suggest-a-test",{"title":2954,"description":2955,"ogTitle":2954,"ogDescription":2955,"noIndex":6,"ogImage":1490,"ogUrl":2956,"ogSiteName":686,"ogType":687,"canonicalUrls":2956,"schema":2957},"ML experiment: Generate tests for code changes","Learn how GitLab is experimenting with ML-powered test suggestions in this latest installment of our ongoing 'AI/ML in DevSecOps' series.","https://about.gitlab.com/blog/merge-request-suggest-a-test","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"ML experiment: Generate tests for code changes\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kai Armstrong\"}],\n        \"datePublished\": \"2023-04-27\",\n      }",{"title":2954,"description":2955,"authors":2959,"heroImage":1490,"date":2960,"body":2961,"category":781,"tags":2962},[1592],"2023-04-27","\n\n\u003Ci>This blog post is part of an ongoing series about GitLab's journey to [build and integrate AI/ML into our DevSecOps platform](/blog/ai-ml-in-devsecops-series/). The series starts here: [What the ML is up with DevSecOps and AI?](/blog/what-the-ml-ai/). Throughout the series, we'll feature blogs from our product, engineering, and UX teams to showcase how we're infusing AI/ML into GitLab.\u003C/i>\n\nProposing changes and new features via merge requests is great, but what about the tests? Sometimes, tests can be the hardest part of any code change you make. Maybe you're not sure how to start writing the tests? Maybe the test doesn't cover all the scenarios that need to be tested? Maybe you just want to get a second opinion on the tests that were written? We believe that we can use generative AI and large language models (LLMs) to help provide relevant test coverage for the proposed changes, so reviewers and authors can have confidence in the quality of code changes being submitted.\n\nIn a rapid prototype, [Phil Hughes](https://gitlab.com/iamphill), Staff Frontend Engineer for our [Code Review Group](https://handbook.gitlab.com/handbook/product/categories/#code-review-group), used AI to generate suggested test coverage for changes directly in the [merge request](https://docs.gitlab.com/ee/user/project/merge_requests/). He added a new option on merge request files to provide suggested tests in a sidebar:\n\n![Merge request test generation AI](https://about.gitlab.com/images/blogimages/merge-request-generate-tests-ai.gif){: .shadow}\n\n## Iterating on AI/ML features\n\nWhile just an experiment today, we are iterating on how to effectively bring features like this to our customers. We're beginning by generating these test suggestions, and seeking ways to incorporate them into the review flow. We're exploring ideas like:\n\n- Automatic detection of missing tests, with suggestions to add coverage\n- Automated review of the proposed tests in the merge request, for appropriateness and completeness\n\nThis experiment is just the start of the ways we're infusing GitLab with AI/ML capabilities to help GitLab users become more efficient and effective at their jobs. We are [looking across the software development lifecycle](/blog/what-the-ml-ai/) for painful and time-consuming tasks that are ideal for AI-assisted features. We'll continue to share these demos throughout this blog series.\n\nInterested in using these AI-generated features? [Join our waitlist](https://forms.gle/9eeUkPJauKsbLaoz5) and share your ideas.\n\nContinue reading our \"[AI/ML in DevSecOps](https://about.gitlab.com/blog/ai-ml-in-devsecops-series/)\" series.\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[9,848,719,717],{"slug":2964,"featured":6,"template":698},"merge-request-suggest-a-test","content:en-us:blog:merge-request-suggest-a-test.yml","Merge Request Suggest A Test","en-us/blog/merge-request-suggest-a-test.yml","en-us/blog/merge-request-suggest-a-test",{"_path":2970,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2971,"content":2975,"config":2982,"_id":2984,"_type":14,"title":2985,"_source":16,"_file":2986,"_stem":2987,"_extension":19},"/en-us/blog/migrating-by-direct-transfer-is-generally-available",{"config":2972,"title":2973,"description":2974},{"noIndex":6},"Migrating by direct transfer is generally available","Learn how to migrate GitLab groups and projects efficiently between GitLab instances with performant and secure migration by direct transfer.",{"title":2973,"description":2974,"authors":2976,"heroImage":2978,"date":2979,"body":2980,"category":848,"tags":2981},[2977],"Magdalena Frankiewicz","https://res.cloudinary.com/about-gitlab-com/image/upload/v1753898687/nlxenzmbdk62dlylt3ey.png","2025-07-31","Migrating GitLab groups and projects by direct transfer is now generally available from GitLab 18.3. This brings an easy-to-use and automated way of migrating GitLab resources between GitLab instances to an even broader audience. \n\nUsing [direct transfer](https://docs.gitlab.com/user/group/import/) enables you to easily create a copy of chosen GitLab resources on the same or another GitLab instance. You can use either the UI or API. The UI is intuitive and straightforward, while [the API](https://docs.gitlab.com/ee/api/bulk_imports.html) gives you additional flexibility in terms of choosing resources to be copied.\n\nMigrating by direct transfer is a major improvement from [migrating groups and projects using file exports](https://docs.gitlab.com/ee/user/project/settings/import_export.html#migrate-projects-by-uploading-an-export-file) because of the following:\n\n* You don't need to manually export each individual group and project to a file and then import all those export files to a new location. Now, you can directly migrate any top-level group you have the Owner role for with all its sub-groups and projects.\n* It allows for [post-import user contribution mapping](https://about.gitlab.com/blog/streamline-migrations-with-user-contribution-and-membership-mapping/) (such as issue or comment authorship), which gives you greater flexibility and control.\n* It works reliably with large projects. Thanks to resource batching and concurrent execution of import and export processes the chance of interruption or timeout is significantly lowered. \n* It offers better insights into the migration while it runs as well as after it completes. In the UI you can observe as the numbers grow as more items are imported. Then you can [review the results](https://docs.gitlab.com/user/group/import/direct_transfer_migrations/#review-results-of-the-import). You can see that an item was imported thanks to an `Imported` badge on items in the GitLab UI.\n\nWe’ve come a long way since GitLab 14.3 when we started supporting the direct migration of the group resources. In GitLab 15.8, we [extended this functionality to projects as a beta](https://about.gitlab.com/blog/2023/01/18/try-out-new-way-to-migrate-projects/). Since then, we have worked to improve the efficiency and reliability of importing, especially for large projects. We thoroughly reviewed the feature from a security and instance stability standpoint. \n\nTo give an example of the sizes of the groups and projects we've tested with, and their import duration, we've seen successful imports of:\n\n* 100 projects (19.9k issues, 83k merge requests, 100k+ pipelines) that migrated in 8 hours\n* 1,926 projects (22k issues, 160k merge requests, 1.1 million pipelines) that migrated in 34 hours\n\nOn GitLab.com, migrating by direct transfer is enabled by default. On GitLab Self-Managed and on GitLab Dedicated, an administrator must [enable the feature in application settings](https://docs.gitlab.com/ee/administration/settings/import_and_export_settings.html#enable-migration-of-groups-and-projects-by-direct-transfer).\n\n## When to use migrating by direct transfer and how to get the best results\n\nMigrating by direct transfer requires network connection between instances or GitLab.com. Therefore, customers that use air-gapped networks with no connectivity between their GitLab instances still have to use file exports to copy their GitLab data. They will be able to use migrating groups and projects by direct transfer after we extend this solution to also [support offline instances](https://gitlab.com/groups/gitlab-org/-/epics/8985).\n\nBefore you attempt a migration, review [documentation](https://docs.gitlab.com/user/group/import/), including [prerequisites](https://docs.gitlab.com/user/group/import/direct_transfer_migrations/#prerequisites), [group items](https://docs.gitlab.com/ee/user/group/import/#migrated-group-items), and [project items](https://docs.gitlab.com/ee/user/group/import/#migrated-project-items) that are migrated. Some items are excluded from migration or not yet supported.\n\n### Migrate between most recent possible versions\n\nWe recommend migrating between versions that are as recent as possible. Update the source and destination instances to take advantage of all improvements and bug fixes we’ve added over time.\n\n### Prepare for user contribution mapping post migration\n\nFamiliarize yourself with [user contribution and membership mapping process](https://docs.gitlab.com/user/project/import/#user-contribution-and-membership-mapping) so you know what to expect after migration completes and what are the next steps for you to take.\n\n### Review options to reduce migration duration\n\nDepending on where you’re migrating to, GitLab.com, a self-managed instance, or Dedicated, you can employ [various strategies to reduce the migration duration](https://docs.gitlab.com/ee/user/group/import/#reducing-migration-duration).\n\n## How can I review the results?\n\nYou can view all groups and projects migrated by you by direct transfer listed on the [group import history page](https://docs.gitlab.com/user/group/import/direct_transfer_migrations/#group-import-history). For each group and project, you can view statistics for imported items and dig down into details in case some items were not imported. Alternatively, you can use [API endpoints](https://docs.gitlab.com/ee/api/bulk_imports.html#list-all-group-or-project-migrations-entities) to do the same.\n\nIn cases where most of your projects completed successfully but one or two end up missing some relations, like merge requests or issues, we recommend that you try re-importing those projects [by using the API](https://docs.gitlab.com/ee/api/bulk_imports.html#start-a-new-group-or-project-migration).\n\n![](https://res.cloudinary.com/about-gitlab-com/image/upload/v1753961409/ja8agmwarwxxlo9vmqbo.gif)\n\n## What’s next for migrating by direct transfer?\n\nWe are excited to bring migration by direct transfer to general availability and hope you are too! We want to hear from you. What's the most important missing piece for you? What else can we improve? Let us know in the [migration by direct transfer feedback issue](https://gitlab.com/gitlab-org/gitlab/-/issues/284495) and we'll keep iterating!",[9,848,719],{"featured":91,"template":698,"slug":2983},"migrating-by-direct-transfer-is-generally-available","content:en-us:blog:migrating-by-direct-transfer-is-generally-available.yml","Migrating By Direct Transfer Is Generally Available","en-us/blog/migrating-by-direct-transfer-is-generally-available.yml","en-us/blog/migrating-by-direct-transfer-is-generally-available",{"_path":2989,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":2990,"content":2995,"config":3000,"_id":3002,"_type":14,"title":3003,"_source":16,"_file":3004,"_stem":3005,"_extension":19},"/en-us/blog/migrating-from-bamboo-to-gitlab-cicd",{"title":2991,"description":2992,"ogTitle":2991,"ogDescription":2992,"noIndex":6,"ogImage":880,"ogUrl":2993,"ogSiteName":686,"ogType":687,"canonicalUrls":2993,"schema":2994},"How to migrate from Bamboo to GitLab CI/CD","With the fast approaching EOL of Atlassian Server products, including Bamboo, this blog post explains how users of Bamboo can migrate to GitLab CI/CD.","https://about.gitlab.com/blog/migrating-from-bamboo-to-gitlab-cicd","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to migrate from Bamboo to GitLab CI/CD\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Abubakar Siddiq Ango\"}],\n        \"datePublished\": \"2023-10-26\",\n      }",{"title":2991,"description":2992,"authors":2996,"heroImage":880,"date":2997,"body":2998,"category":10,"tags":2999},[1455],"2023-10-26","_Atlassian is ending support for all Server products in February 2024.\n[Learn more about the benefits of migrating from Atlassian to GitLab\nhere](https://about.gitlab.com/move-to-gitlab-from-atlassian/)._\n\n\nThe clock is ticking towards the February 15, 2024, [end-of-life date\nAtlassian has set for their Server\nproducts](https://about.gitlab.com/blog/atlassian-server-ending-move-to-a-single-devsecops-platform/).\nUsers whose workflows rely on on-premises deployments of Atlassian Server\nproducts are faced with the choice of upgrading to Atlassian’s Data Center\nor Cloud products or finding alternatives. \n\n\nOne of the Atlassian products that is impacted is Bamboo, a CI/CD solution.\nWhether you're simply looking for a new CI/CD tool or you're looking to\nconsolidate your entire toolchain, the Atlassian Server end of life is a\ngreat opportunity to make the move to GitLab to take advantage of the\nautomation, scalability, and security of an end-to-end DevSecOps platform.\n\n\nIn this blog post, we'll cover the steps you can take to migrate your Bamboo\nCI/CD setup to GitLab CI/CD.\n\n\n## How is GitLab CI/CD different from Bamboo?\n\n\n### Organization\n\n\nBamboo is structured around Projects and Plans. CI/CD jobs are grouped into\nstages, which are defined in a Bamboo plan along with other configurations\nthat determine how jobs run. Bamboo projects are used to organize plans,\nwhich are classified into Build and Deployment plans. \n\n\nAs the name implies, Build plans can be configured to pull code from\nconfigured repositories and generate artifacts. These artifacts are picked\nby jobs defined in Deployment plans and are deployed to environments\nconfigured in Bamboo. Bamboo jobs are also composed of tasks, which can be a\nscript, a task to pull code from a repository, or a task specific to a\ntechnology.\n\n\nYou also need to add code repositories to a Bamboo plan or a project, making\nit available to all plans under it, and set triggers for how Bamboo detects\nchanges and runs builds.\n\n\nGitLab is organized differently. Everything is in a single platform, with\nyour CI/CD configuration provided as part of your code in a `.gitlab-ci.yml`\nfile, from a group’s compliance pipeline configuration, or Auto DevOps when\nenabled and the `.gitlab-ci.yml` file is not found in a project.\n\n\nGitlab CI/CD configurations are composed of jobs, grouped into stages. How\nthe jobs are triggered can be controlled by CI/CD `rules` and there is no\nseparate configuration for deployments. Deployment jobs can be defined in\nthe same CI/CD script in a `deploy` stage, with the [deployment\nenvironment](https://docs.gitlab.com/ee/ci/environments/) set.\n\n\n### Agents vs Runners\n\n\nBamboo uses\n[Agents](https://confluence.atlassian.com/confeval/development-tools-evaluator-resources/bamboo/bamboo-remote-agents-and-local-agents)\n\nto run builds and deployments. These can be local agents running on the\nBamboo server or\n\nremote agents running external to the server. GitLab uses a similar concept\nto agents,\n\ncalled [GitLab Runner](https://docs.gitlab.com/runner/), which uses\n[executors](https://docs.gitlab.com/runner/executors/)\n\nto run builds. Examples of executors include SSH, Docker, and Kubernetes.\nYou can choose to\n\nuse GitLab [SaaS runners](https://docs.gitlab.com/ee/ci/runners/) or deploy\nyour own [self-managed\nrunners](https://docs.gitlab.com/runner/install/index.html).\n\n\n### Bamboo Specs vs .gitlab-ci.yml file\n\n\nBamboo is largely configured via the Bamboo UI but can also be configured as\ncode using Bamboo Specs. Bamboo Specs can be defined using Java and other\nJVM languages or using YAML, with Java having more complete feature coverage\nthan YAML. Bamboo Specs can be defined and stored in spec repositories, then\nlinked to Bamboo projects.\n\n\nThe `.gitlab-ci.yml` file is central to the CI/CD workflow in GitLab. When\nincluded in a project, the defined configurations are executed against the\nproject; otherwise, [Auto\nDevOps](https://docs.gitlab.com/ee/topics/autodevops/) automatically builds\nand deploys your application, when enabled. Templates and CI/CD components\ncan also be added to `.gitlab-ci.yml` for complex use cases.\n\n\n## How GitLab steps up your workflow\n\n\nIn addition to building and deploying your application, GitLab provides a\nsuite of features that allows for building secure applications fast and\nefficiently. These include:\n\n\n- [Application\nsecurity](https://docs.gitlab.com/ee/user/application_security/): GitLab\nanalyzes your application across the stages of the software development\nlifecycle with security scans such as Static Application Security Testing\n(SAST), Secret Detection, Infrastructure as Code (IaC) Scanning, Dependency\nScanning, License Scanning, Coverage-guided Fuzz Testing, Container\nScanning, API Security, Dynamic Application Security Testing (DAST), and\nOperational Security Scanning.\n\n- Compliance and security policies: Understanding the results of security\nscans and putting policies in place is crucial to ensuring secure\napplications. You can set up Scan Execution or Result policies to ensure\nadditional scans or approval requirements are added to comply with\nregulatory or self-imposed requirements.\n\n- [CI/CD catalog](https://docs.gitlab.com/ee/ci/components/catalog.html):\nParts of CI/CD configurations that are used across multiple projects can be\nturned into\n[components](https://docs.gitlab.com/ee/ci/components/index.html#components-repository)\nstored in component repositories that are discoverable in the CI/CD catalog.\n\n- Packages and registries: Custom or local replicas of popular packages can\nbe hosted with the [GitLab Package\nRegistry](https://docs.gitlab.com/ee/user/packages/package_registry/index.html).\nYou can also host container images with the [GitLab Container\nRegistry](https://docs.gitlab.com/ee/user/packages/container_registry/index.html)\nand Terraform modules with the [GitLab Terraform Module\nRegistry](https://docs.gitlab.com/ee/user/packages/terraform_module_registry/index.html).\nIf you frequently use public images or packages, you can use the [Dependency\nProxy](https://docs.gitlab.com/ee/user/packages/dependency_proxy/index.html)\nto maintain a local cache.\n\n\n[Learn more about other ways to automate your entire workflow with GitLab\nCI/CD](https://about.gitlab.com/solutions/continuous-integration/).\n\n\n## Convert Bamboo Specs to .gitlab-ci.yml script\n\n\nFor the purpose of this blog post, we will focus on [Bamboo YAML\nSpecs](https://docs.atlassian.com/bamboo-specs-docs/9.3.0/specs.html?yaml).\nYou can export your Bamboo Plans as YAML Spec — [learn more\nhere](https://confluence.atlassian.com/bamboo/exporting-existing-plan-configuration-to-bamboo-yaml-specs-1018270696.html).\nNow, lets walk through converting your Bamboo YAML Specs into GitLab CI/CD\nconfiguration.\n\n\n### Container image\n\n\nFirst is defining the container image of the container your jobs will run\nin. By default, Bamboo uses Agents, which depend on how the host machines\nare configured. You can replicate the Agent’s environment into a container\nimage hosted in the [GitLab Container\nRegistry](https://docs.gitlab.com/ee/user/packages/container_registry/).  \n\n\nIf you already run Bamboo jobs in a container image, it will look like this\nin your spec:\n\n\n```yaml\n\n---\n\nversion: 2\n\n# ...\n\ndocker: ubuntu\n\n```\n\n\nThis might be defined at the plan or job level. You can define it in GitLab\nas follows:\n\n\n```yaml\n\nimage: ubuntu\n\n```\n\n\n[Learn more about running CI/CD jobs in containers\nhere](https://docs.gitlab.com/ee/ci/docker/using_docker_images.html). If\nyour use case does not include containers, you can explore [other\nexecutors](https://docs.gitlab.com/runner/executors/).\n\n\n### Stages\n\n\nIn Bamboo, stages and their list of jobs are defined first, before the job\ndefinitions:\n\n\n```yaml\n\nversion: 2\n\nstages:\n  - First Stage:\n      jobs:\n        - Job 1A \n        - Job 1B\n  - Second Stage:\n      jobs:\n        - Job 2A \n        - Job 2B\n\nJob 1A:\n  tasks:\n    - clean\n    - script\n        - touch file1A.txt\n\nJob 1B:\n  tasks:\n    - clean\n    - script\n        - touch file1B.txt\n\nJob 2A:\n  tasks:\n    - clean\n    - script\n        - touch file2A.txt\n\nJob 2B:\n  tasks:\n    - clean\n    - script\n        - touch file2B.txt\n```\n\n\nIn GitLab, you list your stages in the order in which you want their jobs to\nrun:\n\n\n```yaml\n\nstages:\n  - build\n  - test\n  - deploy\n\njob1:\n  stage: build\n  script:\n    - echo \"This job compiles code.\"\n\njob2:\n  stage: test\n  script:\n    - echo \"This job tests the compiled code. It runs when the build stage completes.\"\n\njob3:\n  script:\n    - echo \"This job also runs in the test stage\".\n\njob4:\n  stage: deploy\n  script:\n    - echo \"This job deploys the code. It runs when the test stage completes.\"\n  environment: production\n```\n\n\nAll the jobs in a stage run in parallel and when they succeed, execution\nproceeds to the next stage. This only changes in complex pipelines where a\njob depends on another using\n[`needs`](https://docs.gitlab.com/ee/ci/yaml/index.html#needs).\n\n\n### Variables\n\n\nBamboo has System, Global, Project, Plan, and Build-specific variables,\nwhich can be accessed using the format `${system.variableName}` for system\nvariables and `${bamboo.variableName}` for others. Periods (.) are replaced\nby underscores (_) when variables are accessed in scripts.\n\n\n```yaml\n\nversion: 2\n\n# ...\n\nvariables:\n  username: admin\n  releaseType: milestone\n\nDefault job:\n  tasks:\n    - script: echo 'Release Type is $bamboo_releaseType'\n```\n\n\nIn GitLab, variables can be defined at group, project, CI Script, and job\nlevels. In GitLab self-managed and GitLab Dedicated, administrators can\ndefine variables at the instance level. GitLab allows protecting, masking,\nand expanding variables. Protected variables are only accessible for\npipelines running against the default or protected branches. [Learn more\nabout CI/CD variables](https://docs.gitlab.com/ee/ci/variables/index.html)\nand [where you can use\nthem](https://docs.gitlab.com/ee/ci/variables/where_variables_can_be_used.html).\n\n\nHere is an example:\n\n\n```yaml\n\nvariables:\n  GLOBAL_VAR: \"A global variable\"\n\njob1:\n  variables:\n    JOB_VAR: \"A job variable\"\n  script:\n    - echo \"Variables are '$GLOBAL_VAR' and '$JOB_VAR'\"\n\njob2:\n  script:\n    - echo \"Variables are '$GLOBAL_VAR' and '$JOB_VAR'\"\n```\n\n\n### Build Jobs\n\n\nBamboo Build Jobs are composed of tasks, each of which is a small unit of\nwork that can be anything from checking out source code to injecting\nvariables or running a script.\n\n\n```yaml\n\nversion: 2\n\nstages:\n  - Run Tests:\n      jobs:\n        - Test Ruby \n\nTest Ruby :\n  key: TEST\n  tasks:\n  - checkout:\n      force-clean-build: false\n      description: Checkout Default Repository\n  - script:\n      interpreter: SHELL\n      scripts:\n      - |-\n        ruby -v  # Print out ruby version for debugging\n        bundle config set --local deployment true  \n        bundle install -j $(nproc)\n        rubocop\n        rspec spec\n      description: run bundler & rspec\n\n```\n\n\nIn this example, the plan has two tasks, checkout and script. The checkout\ntasks pull an updated version of the code repository, which is made\navailable for the script task to execute its commands against. \n\n\n[Jobs in GitLab](https://docs.gitlab.com/ee/ci/jobs/) are composed of script\ncommands:\n\n\n```\n\nimage: ruby:latest\n\n\nstages:\n  - test\n\nrspec:\n  stage: test\n  script:\n    - ruby -v\n    - bundle config set --local deployment true \n    - bundle install -j $(nproc)\n    - rubocop\n    - rspec spec\n```\n\n\nIn the example above, the stage the job belongs to is specified with the\n`stage` keyword and the commands to be executed by the GitLab runner for the\njob are listed under `script`.\n\n\nIn Bamboo, you can use\n[executables](https://confluence.atlassian.com/bamboo/defining-a-new-executable-capability-289277164.html),\nsuch as Ant, Maven, or PHPUnit, in a task to build your application. In\nGitLab, you can package the binaries you need in a custom container image\nand use it as your CI/CD image.\n\n\n### Deployment jobs\n\n\nIn Bamboo, Deployment projects organize software releases or environments\napplications are deployed to. A deployment plan can have a release\ndefinition:\n\n\n```yaml\n\n---\n\nversion: 2\n\n\ndeployment:\n  name: Release Software\n  source-plan: BUILD-APP\n\nrelease-naming: release-1.1\n\n```\n\n\nFor releases, you specify the plan it should get the generated artifacts\nfrom. And for deployment for environments:\n\n\n```yaml\n\n---\n\nversion: 2\n\n# ...\n\nenvironments:\n  - Test\n  - QA\n  - Prod\n\nTest:\n  tasks:\n    - clean\n    - artifact-download:\n        destination: /workdir\n```\n\n\nIn GitLab CI/CD, you can create a [deployment\njob](https://docs.gitlab.com/ee/ci/jobs/#deployment-jobs)\n\nthat deploys to an\n[environment](https://docs.gitlab.com/ee/ci/environments/index.html) or\ncreate a [release](https://docs.gitlab.com/ee/user/project/releases/).\n\nFor deploying to an environment, you use the\n[`environment`](https://docs.gitlab.com/ee/ci/yaml/#environment) keyword:\n\n\n```yaml\n\ndeploy-to-production:\n  stage: deploy\n  script:\n    - # Run Deployment script\n    - ./.ci/deploy_prod.sh\n  environment:\n    name: production\n```\n\n\nIf you are creating a release instead, you use the\n[`release`](https://docs.gitlab.com/ee/ci/yaml/#release)\n\nkeyword along with the\n[release-cli](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs)\n\ntool to create releases for [Git\ntags](https://docs.gitlab.com/ee/user/project/repository/tags/).\n\nThe `release` section is executed after the `script` section, which must\nexist.\n\nIf you don’t have any script commands to run, you can put a placeholder\ncommand;\n\nfor example, `echo` a message.\n\n\n```yaml\n\nrelease_job:\n  stage: release\n  image: registry.gitlab.com/gitlab-org/release-cli:latest\n  rules:\n    - if: $CI_COMMIT_TAG                  # Run this job when a tag is created manually\n  script:\n    - echo \"Building release version\"\n  release:\n    tag_name: $CI_COMMIT_TAG\n    name: 'Release $CI_COMMIT_TAG'\n    description: 'Release created using the release-cli.'\n```\n\n\n### Rules and workflows\n\n\nIn Bamboo, triggers can be used to control how Jobs are executed. Triggers\ncan be a periodic poll of the repository for changes or a webhook that\nnotifies Bamboo of changes to the repository. Trigger conditions can be\nenabled in the Bamboo web UI to make sure the build only runs if other plans\nare passing.\n\n\nExample of a trigger:\n\n\n```yaml\n\n---\n\nversion: 2\n\ntriggers:\n  - polling: 130\n  - cron: 0 * * * ? *\n```\n\n\nIn GitLab, [CI/CD pipelines](https://docs.gitlab.com/ee/ci/pipelines/) can\nbe triggered by a commit/push, a merge, manually, on schedule, or with\n[pipeline\nsubscriptions](https://docs.gitlab.com/ee/ci/pipelines/#trigger-a-pipeline-when-an-upstream-project-is-rebuilt).\nJobs in a pipeline can further be controlled using `rules` or `workflow`.\nLearn more about [Job\nControl](https://docs.gitlab.com/ee/ci/jobs/job_control.html) and [pipeline\nworkflows](https://docs.gitlab.com/ee/ci/yaml/workflow.html#) in GitLab\nCI/CD. \n\n\nHere's an example using `rules` in GitLab CI/CD:\n\n\n```yaml\n\nworkflow:\n  rules:\n    - changes:\n      - .gitlab/**/**.md\n      when: never\n```\n In this example, pipelines are never executed when `.md` files changed in the `.gitlab` folder.\n\n#### Artifacts\n\n\nYou can define Job artifacts using the `artifacts` keyword in both GitLab\nand Bamboo.\n\n\nIn Bamboo, artifacts can be defined as follows:\n\n\n```yaml\n\n---\n\nversion: 2\n\n# ...\n  artifacts:\n    -\n      name: Test Reports\n      location: target/reports\n      pattern: '*.xml'\n      required: false\n      shared: false\n    -\n      name: Special Reports\n      location: target/reports\n      pattern: 'special/*.xml'\n      shared: true\n```\n\n\nIn the Bamboo Spec above, artifacts are defined with a name, location,\npattern, and optionally\n\nthe ability to share the artifacts with other jobs or plans. You can go\nfurther to define jobs that\n\ncan subscribe to the artifact.\n\n\n`artifact-subscriptions` is used to access artifacts from another job in the\nsame plan:\n\n\n```yaml\n\nTest app:\n  artifact-subscriptions:\n    -\n      artifact: Test Reports\n      destination: deploy\n```\n\n\n`artifact-download` is used to access artifacts from jobs in a different\nplan.\n\n\n```yaml\n\n---\n\nversion: 2\n\n# ...\n  tasks:\n    - artifact-download: \n        source-plan: PROJECTKEY-PLANKEY\n```\n\n\nYou need to provide the key of the plan you are downloading artifacts from\nin the `source-plan` keyword.\n\n\nIn GitLab, all artifacts from completed jobs in the previous stages are\ndownloaded by default.\n\nHere is an example of an artifact definition in GitLab:\n\n\n```yaml\n\npdf:\n  script: xelatex mycv.tex\n  artifacts:\n    name: \"pdf-files\"\n    public: false\n    untracked: true\n    paths:\n      - pdfs/\n    exclude:\n      - pdfs/*.tex\n```\n\n\nIn the CI/CD script above:\n\n\n- The name of the artifact is specified laterally. You can choose to make it\ndynamic by using a CI/CD variable.\n\n- The `public` keyword is used to set whether the artifact should be\npublicly available. This is not enabled by default\n  on self-managed GitLab instances. An administrator can enable it with the [feature flag](https://docs.gitlab.com/ee/administration/feature_flags/)\n  named `non_public_artifacts`.\n- You can set the `untracked` to include or exclude Git untracked files\nalong with those specified using `paths`.\n\n\nRead more about GitLab CI/CD [job\nartifacts](https://docs.gitlab.com/ee/ci/jobs/job_artifacts.html).\n\n\n## How to plan your migration\n\n\nPlanning a migration to Gitlab CI/CD from Bamboo doesn't start with\nconverting your Bamboo plan to GitLab CI/CD scripts. It starts with aligning\nwith your leadership and stakeholders and clearly communicating the vision\nof the migration. [Check out our documentation to learn more about managing\norganizational\nchanges](https://docs.gitlab.com/ee/ci/migration/plan_a_migration.html).\nOnce you have the necessary buy-in, you can proceed with the following\nsteps:\n\n\n- [Import your projects](https://docs.gitlab.com/ee/user/project/import/) to\nGitLab.\n\n- Identify the necessary binaries and build tools needed to build your\napplication, along with their dependencies.\n\n- Define the flow of your pipeline, which jobs depend on each other, and the\nnecessary triggers.\n\n- Learn more about [key GitLab CI/CD\nfeatures](https://docs.gitlab.com/ee/ci/index.html).\n\n- Identify the credentials and variables needed in your pipeline and define\nthem in the variable section of your project's CI/CD settings or using a\nsecret manager.\n\n- Follow [this\ntutorial](https://docs.gitlab.com/ee/ci/quick_start/index.html) to create\nyour first GitLab pipeline; you can also explore more [complex\npipelines](https://docs.gitlab.com/ee/ci/quick_start/tutorial.html).\n\n- Iterate and test your GitLab CI/CD pipelines and review [.gitlab-ci.yml\nkeyword reference](https://docs.gitlab.com/ee/ci/yaml/index.html).\n\n\nReady to make the move? [We’re here to\nhelp](https://about.gitlab.com/sales/).\n",[9,496],{"slug":3001,"featured":6,"template":698},"migrating-from-bamboo-to-gitlab-cicd","content:en-us:blog:migrating-from-bamboo-to-gitlab-cicd.yml","Migrating From Bamboo To Gitlab Cicd","en-us/blog/migrating-from-bamboo-to-gitlab-cicd.yml","en-us/blog/migrating-from-bamboo-to-gitlab-cicd",{"_path":3007,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3008,"content":3013,"config":3019,"_id":3021,"_type":14,"title":3022,"_source":16,"_file":3023,"_stem":3024,"_extension":19},"/en-us/blog/modern-software-development-problems-require-modern-ai-powered-devsecops",{"title":3009,"description":3010,"ogTitle":3009,"ogDescription":3010,"noIndex":6,"ogImage":839,"ogUrl":3011,"ogSiteName":686,"ogType":687,"canonicalUrls":3011,"schema":3012},"Modern software development problems require modern AI-powered DevSecOps","Learn how applying AI can help solve common development challenges.","https://about.gitlab.com/blog/modern-software-development-problems-require-modern-ai-powered-devsecops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Modern software development problems require modern AI-powered DevSecOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"William Arias\"}],\n        \"datePublished\": \"2023-09-07\",\n      }",{"title":3009,"description":3010,"authors":3014,"heroImage":839,"date":3016,"body":3017,"category":781,"tags":3018},[3015],"William Arias","2023-09-07","\nThe landscape of software development is already being impacted by the integration of AI tools. GitLab is making that impact a positive one. Infusing AI throughout the software development lifecycle lowers the barrier for everyone to contribute. Let's take a look how organizations can evolve the idea _\"every company is a software company\"_ into _\"every company should be an AI-first company\"_ and how this transformation can happen by embracing AI-powered DevSecOps.\n\nAn effective way to demonstrate how AI can be a game-changer for software development teams is to walk through a detailed scenario. In this example, you'll see how applying [GitLab Duo](https://about.gitlab.com/gitlab-duo/), the suite of AI capabilities powering workflows, to a dilemma that many organizations face – how to automate complex customer-facing tools – can improve the experience for DevSecOps teams and customers alike.\n\n## Challenge: Keeping customer Q&A systems from going stale\nImagine a large financial services firm has an extensive FAQ section on its website but keeping that information up to date and easy to navigate has become increasingly difficult. Also, the FAQs don't cover queries that are less frequent but should be easy to respond to.\n\n![FAQ](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/faq-improved.gif)\n\nTo resolve this, the company proposed building an AI-enabled Q&A system that not only answers common queries but also other finance-related questions. The process to build the AI-enabled system described above can look like this:\n\n![process](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/process-demo.png)\n\n### Problem definition and collaboration\nThe journey begins with a GitLab issue. This is where the team collaborates, discusses ideas, and brainstorms to define the problem and scope of work. Collaborating on solving the Q&A system problem results in a lengthy issue thread where it can be challenging to quickly understand the status of the work. Anyone new to the issue or even current participants may need to spend considerable time reading comments to get an overview of the problem status and the decisions that have been made. AI-driven text summarization simplifies understanding of the comments, allowing developers and business teams to align on the problem and requirements.\n\n![AI-driven text summary](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/summary-hd.png)\n\nText summarization applied to issue comments \n{: .note.text-center}\n\nGitLab provides an AI-generated summary right in the issue where all the collaboration took place, thus helping development teams to get an overview of the main points and takeaways. The AI-generated summary enables developers and other team members to quickly extract and review key points from the issue without having to read through long conversations.\n\n### Solution development\nThe proposed solution involves leveraging a large language model (LLM) to build a Q&A system. The AI-generated summary allows developers to quickly break down the requirements and store them in GitLab using [Requirements management](https://docs.gitlab.com/ee/user/project/requirements/).  The requirements are stored as easy-to-understand items with their own criteria of success and expected behavior as depicted in the figure below:\n\n![requirements](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/requirements.png)\n\nAI Q&A system requirements in GitLab \n{: .note.text-center}\n\nHaving clear requirements is key to starting implementation of a successful solution, creating a [merge request](https://docs.gitlab.com/ee/user/project/merge_requests/), and iterating on the solution to the problem.\n\nWhile working towards a solution, GitLab Duo Code Suggestions can help developers focus. Leveraging generative AI, Code Suggestions provides relevant suggestions reducing time spent on repetitive or common code. This frees up developers to focus their efforts on complex problems that require deeper understanding of the codebase and business logic. \n\n![code-suggestions](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/code-suggestion.png)\n\nGenerated code speeds up development\n{: .note.text-center}\n\nDevelopers get code suggestions inline in their integrated development environment, or IDE, as they type or after prompting the model with code comments. The suggestions are predicted based on the code written before the cursor and the file extension of the script.\n\n### Efficient code review\nLet's consider that, until this point, developers working on the AI-enabled Q&A system have committed code contributions to build the solution. And it is also evident that infusing AI into the software development lifecycle has allowed the team to move faster. To move faster without compromising quality, however, it’s important to carry out code reviews on all the contributions done so far by the development team. Code reviews help developers share knowledge and maintain high-quality software. Companies like the one in this scenario might have a large number of developers, and identifying suitable reviewers can be challenging and time consuming. To resolve this, the company can leverage [GitLab Duo Suggested Reviewers](https://about.gitlab.com/gitlab-duo/). This feature employs machine learning to suggest the most relevant code reviewers, streamlining and speeding up the review process. \n\n![suggested-reviewers](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/suggested-review-sa.png)\n\nSuggested reviewers appear in the reviewer dropdown\n{: .note.text-center}\n\nThe machine learning algorithm that powers Suggested Reviewers learns from the project’s contribution graph data; the suggestions it generates are contextual to the changes made in the code.   \n\n### Code review summarization and test generation\nAI-driven text summarization helps in understanding suggested code changes derived from the code review at a glance. In our scenario, once the appropriate reviewer has been chosen, this person can go through the code and submit comments, propose changes, or identify potential edge cases that may have been overlooked. Getting a quick summary of all the suggested code changes before diving into the details can potentially speed up software delivery.\n\n![mr-summary](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/MR-Summary.png)\n\nCode Review summary\n{: .note.text-center}\n\nAs part of the review, it is important to make sure that all the functions have been tested. If there was the case of an overlooked test, once again it is possible to leverage generative AI within GitLab to create [test cases](https://docs.gitlab.com/ee/ci/test_cases/).\n\n![suggest-test-cases](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/suggest-test-cases.png)\n\nTest cases generated by AI\n{: .note.text-center}\n\nIn the figure below, we see the test code generated by AI. This provides helpful assertions that can also serve as an inspiration for discovering edge cases that might have not been considered before.\n\n![test cases](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/test-cases-created.png)\n\nSuggested test cases\n{: .note.text-center}\n\nThis solidifies the quality of the project codebase, closing the loop of efficient code reviews.\n\n### Minimizing context switching\nAllowing developers to obtain guidance and answers to GitLab-related questions without leaving the platform can be achieved by interacting with GitLab Duo Chat functionality.This AI-powered feature reduces context switching and enables developers or other team members to ask open questions and request information using natural language. Let's assume that a developer wasn't exactly sure how to leverage AI to generate test cases like the ones requested during the code review. Using GitLab Duo Chat, the developer can ask how to achieve exactly that without having to leave the platform, as depicted in the figure below:\n\n![GitLab Duo Chat](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/chat.png)\n\nGitLab Duo Chat\n{: .note.text-center}\n\nInteracting with the platform using natural language provides a convenient way to achieve results and get things done while minimizing context switching, improving the software delivery experience and speed. Now, speaking of speed, let's dive into the realm of continuous integration/continuous delivery and deployment (CI/CD).\n\n### GitLab CI/CD \nThe AI-infused DevSecOps approach described so far aligns and enhances CI/CD methodologies. The financial services company in this scenario uses these continuous methodologies to deliver software faster since these are proven ways to automatically build, test, secure, and deploy software.\n\n![chatbot-pipeline](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/pipelines.png)\n\nGitLab CI/CD pipeline\n{: .note.text-center}\n\nThe figure above depicts the CI/CD pipeline that is triggered and used in the development of our LLM Financial Q&A system. The jobs it executes are:\n\n- Build: creates the container with its respective code and dependencies\n- Test: unit testing and security scanners, which help ensure that no code vulnerabilities are being introduced \n- Deploy: puts the solution in the hands of end users\n\nOnce the solution is deployed, end users can ask questions to it, and the FAQ problem can be considered solved.\n\n![chatbot](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/chatbot.gif)\n\nThe AI touchpoints explored in this scenario and that led to the faster development of our AI-powered Q&A system are seamlessly integrated within DevSecOps methodologies, enhancing the development and operations experience.\n\n![devsecops-ml](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/devsecops-embedded.png)\n\nUltimately, this increases the likelihood of a successful and secure deployment of the AI-powered Q&A system.\n\n### Recap\nGoing back to the process overview, in the following table we see how the different AI touchpoints are used throughout the software development lifecycle.\n\n|  | What AI-powered DevSecOps can do for you | Feature |\n| ------ | ------ | ------ |\n|![brainstorming](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/brainstorm.png) | AI generates a summary of the discussions and provide the most relevant information for your team to move forward in the solution development   |[Summarize issues](https://docs.gitlab.com/ee/user/ai_features.html#summarize-issue-discussions)       |\n|![requirements](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/solution-requirements.png)       | The team agrees on a chatbot and break down the application requirements and set criteria it must fulfill       |  [Requirements management](https://docs.gitlab.com/ee/user/project/requirements/)       |\n|![develop](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/develop.png)        | Developers leverage Code Suggestions to speed up code and generate tests       |   [Code Suggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html)     |\n|![reviewer](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/suggested-reviewer.png)        | Quickly find the most suitable person to review code changes and move on in the delivery process       |  [Suggested Reviewers](https://docs.gitlab.com/ee/user/project/merge_requests/reviews/data_usage.html#:~:text=Suggested%20Reviewers%20is%20the%20first,and%20GitLab%20user%20account%20metadata.)      |\n|![code-review](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/review.png)        |  Summarize Merge Request, which includes code summary, helps contributors understand the most important changes that need to be addressed      | [Summarize Merge Request](https://docs.gitlab.com/ee/user/ai_features.html#summarize-merge-request-changes)      |\n|![pipeline](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/buildtest.png)        | CI/CD and integrated security       |   [CI/CD testing](https://docs.gitlab.com/ee/ci/testing/)    |\n|![deploy](https://about.gitlab.com/images/blogimages/2023-07-24-modern-problems-modern-devsecops/deploy.png)        | Kubernetes agent, and multi-cloud deployments      |  [Kubernetes integration](https://docs.gitlab.com/ee/user/clusters/agent/)      |\n\nWatch the video walkthrough of the financial services scenario:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/LifJdU3Qagw?si=fpfvuhJQ_jYmYrT2\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\nAs organizations embark on their AI journey, more and better software will have to be created. Drawing insights from DevSecOps combined with AI-powered workflows provides a solid foundation to enjoy the benefits of AI, unlock new use cases, and provide robust solutions that learn from data. Ultimately, AI enables organizations to enhance software development practices and to tackle modern problems with modern solutions.\n\nGet started with GitLab Duo today with this [free trial of GitLab Ultimate](https://gitlab.com/-/trials/new?glm_content=default-saas-trial&glm_source=localhost%2Fsolutions%2Fai%2F).\n",[9,496,717],{"slug":3020,"featured":6,"template":698},"modern-software-development-problems-require-modern-ai-powered-devsecops","content:en-us:blog:modern-software-development-problems-require-modern-ai-powered-devsecops.yml","Modern Software Development Problems Require Modern Ai Powered Devsecops","en-us/blog/modern-software-development-problems-require-modern-ai-powered-devsecops.yml","en-us/blog/modern-software-development-problems-require-modern-ai-powered-devsecops",{"_path":3026,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3027,"content":3033,"config":3041,"_id":3043,"_type":14,"title":3044,"_source":16,"_file":3045,"_stem":3046,"_extension":19},"/en-us/blog/navigate-application-architecture-drift-and-organizational-alignment",{"title":3028,"description":3029,"ogTitle":3028,"ogDescription":3029,"noIndex":6,"ogImage":3030,"ogUrl":3031,"ogSiteName":686,"ogType":687,"canonicalUrls":3031,"schema":3032},"Navigate application architecture drift and organizational alignment","Explore how to manage architecture drift by balancing simplification and team realignment using the FINE Analysis. Ensure efficiency and agility throughout an application's lifecycle.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749676151/Blog/Hero%20Images/navigation.jpg","https://about.gitlab.com/blog/navigate-application-architecture-drift-and-organizational-alignment","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Navigate application architecture drift and organizational alignment\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Stephen Walters\"},{\"@type\":\"Person\",\"name\":\"Lee Faus\"}],\n        \"datePublished\": \"2024-09-18\",\n      }",{"title":3028,"description":3029,"authors":3034,"heroImage":3030,"date":3037,"body":3038,"category":909,"tags":3039},[3035,3036],"Stephen Walters","Lee Faus","2024-09-18","Application architecture drift is a common phenomenon in software development as projects evolve and grow in complexity. When this happens, you face a critical decision: Should you simplify the application architecture to fit the current team topologies, or should you adjust your team topologies to match the changing application architecture? This decision is pivotal for maintaining efficiency, innovation, and success throughout an application's lifecycle, which spans years and includes stages from experimentation to production, maintenance, and, ultimately, the end of support.\n\n## What is application architecture drift?\n\nApplication architecture drift occurs when the initial design and structure of an application no longer align with its current state due to continuous improvement, feature additions, and technology advancements. This drift can lead to increased complexity, technical debt, and potential performance bottlenecks if not properly managed.\n\nTo effectively manage such drift, it's essential to consider the teaming topology that supports the application at different levels of application maturity. If your team structure does not accommodate the complexities of the application architecture, you risk a failure on deliverables, which leads to poor customer satisfaction metrics and loss of customer adoption.\n\nWhen team topologies properly adjust to application complexities, poor decisions on implementation details are minimized, resulting in a more scalable and resilient application architecture. As Conway’s Law states, “Organizations which design systems are constrained to produce systems which are copies of the communication structures of these organizations.\" This can result in unintended design additions due to organizational setup. In most cases, these additions can lead to weakened team identities, uncertain responsibilities, and poor team interactions and communications.\n\n## The role of team topologies in managing architecture drift\n\n[Team topologies](https://teamtopologies.com/) refer to the roles and responsibilities within a team and how they are organized to deliver value. When an application's architecture changes, it's crucial to assess whether your team structure is still optimal or if adjustments are needed. The FINE Analysis, as defined in the [Value Stream Reference Architecture](https://www.vsmconsortium.org/value-stream-reference-architectures), provides a valuable lens for evaluating and realigning team topologies throughout an application's lifecycle. FINE is defined as:\n\n* F = Flow of work\n* I = Impediments that slow down the flow of work\n* N = Needs that drive the potential for flow to happen\n* E = Effort that is used in the form of cognitive load\n\n### Experimentation phase\n\n- **Architecture:** Simple, flexible, and exploratory\n- **Team topology:** Small, cross-functional, adaptive teams\n- **FINE Analysis:** Stream-aligned teams will have a high Flow of work, with little initial Impedance, but with much fluctuation. Needs will be high, with a heavy reliance on enabling teams to establish standards and templates.\n- **Application architecture drift:** This will be frequent with rapid and constant change, but manageable due to early simplicity and smaller adaptive teams\n\n### Production phase\n\n- **Architecture:** More defined, scalable, and robust\n- **Team topology:** Larger, responsible, perceptible teams\n- **FINE Analysis:** The Flow of work is stabilized, but impedance starts to collect in the form of technical debt, issues and vulnerabilities. This drives up the Effort required on stream-aligned teams. At this point, enabling teams should have established ways of working and platform groups should start to reduce the cognitive load on teams. Complicated sub-systems will be defined and should be closely controlled.\n- **Application architecture drift:** This will be frequent with rapid and constant change as before. However, larger teams and a more robust but changing architecture will require higher levels of monitoring and management.\n\n### Maintenance phase\n\n- **Architecture:** Mature, stable, and optimized for efficiency\n- **Team topology:** Sustaining teams\n- **FINE Analysis:** The Needs for stream-aligned teams will reduce and be more dependent on actual customer and business outcomes. The Flow of work is much more impacted by Impediments, in particular any production issues. The Effort on teams can become exhaustive if platform groups are not stabilized and effective, enabling teams have to be responsive to continuous improvement.\n- **Application architecture drift:** Architectural changes will be far less frequent, and team structures will be aligned to ensure system stability. This is dependent upon the stability when exiting the production phase.\n\n### End-of-support phase\n\n- **Architecture:** Legacy, minimal updates, and decommissioning planning\n- **Team topology:** Transition teams\n- **FINE Analysis:** Flow of work is drastically reduced. Impedance will move to one of two ways, either reducing as production issues scale down due to lower customer usage, or increasing at a high cost due to legacy systems.\n- **Application architecture drift:** Minimal, if any, architectural drift, as teams should be focused on decommissioning over production.\n\n## Balancing simplification and realignment\n\nThe experimentation phase is important to establish the correct disciplines from the outset. The greatest risk of application architecture drift is then in the production phase. In maintenance, this risk is reduced, and, by end of support, should be negligible. So it is during the production phase, potentially the longest living phase for any business system, that we must ensure strong discipline to prevent the drift.\n\nWhen faced with architecture drift, organizations must decide between simplifying the application architecture to fit existing team topologies or adjusting team topologies to match the evolving architecture. Both approaches have their merits:\n\n- **Simplifying application architecture:** This approach can reduce complexity and technical debt, making it easier for existing teams to manage the application. However, it may limit the application's potential for growth and innovation.\n- **Adjusting team topologies:** Realigning teams to match the evolving architecture can enhance the application's capabilities and performance. This approach requires a more flexible organizational model and may involve retraining or restructuring teams.\n\nA key aspect is to consider **when** to make these adjustments, and the answer is as soon as possible. To leave adaptations for too long can cause the architectural drift to become so large that it inevitably leads to one of two events:\n\n- **Massive re-architecture:** This approach will lead to reduced effort in delivering new customer value, impacting business outcomes. In its own right, it can generate massive technical debt and increased work backlog for future efforts, resulting in increased team cognitive load.\n\n- **Re-organization:** Realigning teams on any kind of large scale will most certainly impact team morale. It can lead to a strain on key people and result in higher churn, especially of innovative talent. This can lead to lost IP knowledge and a future skills shortage, which in turn has an impact on the future quality of the designs and applications produced.\n\n## Next steps\nManaging application architecture drift is an ongoing challenge that requires a strategic approach to organizational alignment. By leveraging the FINE Analysis of the Value Stream Reference Architecture and understanding the different phases of an application's lifecycle, you can make informed decisions about team topologies and ensure your organization remains agile and efficient. Whether you choose to simplify application architecture or adjust your team structure, the key is to maintain a balance that supports both current needs and future growth.\n\n> [Learn how to manage application value streams](https://about.gitlab.com/solutions/value-stream-management/) with the GitLab DevSecOps platform.\n",[9,3040],"design",{"slug":3042,"featured":91,"template":698},"navigate-application-architecture-drift-and-organizational-alignment","content:en-us:blog:navigate-application-architecture-drift-and-organizational-alignment.yml","Navigate Application Architecture Drift And Organizational Alignment","en-us/blog/navigate-application-architecture-drift-and-organizational-alignment.yml","en-us/blog/navigate-application-architecture-drift-and-organizational-alignment",{"_path":3048,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3049,"content":3054,"config":3060,"_id":3062,"_type":14,"title":3063,"_source":16,"_file":3064,"_stem":3065,"_extension":19},"/en-us/blog/new-cis-gitlab-benchmark-scanner-boosts-security-and-compliance",{"title":3050,"description":3051,"ogTitle":3050,"ogDescription":3051,"noIndex":6,"ogImage":2285,"ogUrl":3052,"ogSiteName":686,"ogType":687,"canonicalUrls":3052,"schema":3053},"New CIS GitLab Benchmark scanner boosts security and compliance","GitLab's gitlabcis scanner determines level of compliance for GitLab projects. Learn how to install and use the tool with this tutorial, as well as what's on the roadmap.","https://about.gitlab.com/blog/new-cis-gitlab-benchmark-scanner-boosts-security-and-compliance","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"New CIS GitLab Benchmark scanner boosts security and compliance\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Mitra Jozenazemian\"},{\"@type\":\"Person\",\"name\":\"Neil McDonald\"},{\"@type\":\"Person\",\"name\":\"Nate Rosandich\"}],\n        \"datePublished\": \"2024-10-29\",\n      }",{"title":3050,"description":3051,"authors":3055,"heroImage":2285,"date":2637,"body":3058,"category":694,"tags":3059},[927,3056,3057],"Neil McDonald","Nate Rosandich","GitLab's CIS Benchmark scanner,\n[gitlabcis](https://gitlab.com/gitlab-org/govern/compliance/engineering/cis/gitlabcis),\nis open source and available. The\n[Python](https://www.python.org/downloads/) CLI tool audits a GitLab project\nagainst the [Center for Internet Security (CIS) GitLab\nBenchmark](https://workbench.cisecurity.org/benchmarks/17538), and delivers\n[recommendations as\ncode](https://gitlab.com/gitlab-org/govern/compliance/engineering/cis/gitlabcis/-/tree/main/gitlabcis/recommendations?ref_type=heads#recommendations)\nformatted in YAML.\n\n\nIn April, we introduced the [CIS GitLab\nBenchmark](https://about.gitlab.com/blog/gitlab-introduces-new-cis-benchmark-for-improved-security/)\nto improve security and offer hardening recommendations to GitLab's\ncustomers. [The benchmark is available for\ndownload](https://workbench.cisecurity.org/benchmarks/17538) from the CIS\nwebsite.\n\n\nIn this article, you'll learn:\n\n* [How to install and use the gitlabcis\nscanner](#how-to-install-and-use-the-gitlabcis-scanner)\n\n* [gitlabcis scanner details](#gitlabcis-scanner-details)\n\n* [GitLab scanner and product roadmap](#gitlab-scanner-and-product-roadmap)\n\n\n## How to install and use the gitlabcis scanner\n\n\nYou can download and install the scanner using pip via\n[pypi](https://pypi.org/project/gitlabcis/), or download the source code\nfrom our [releases\npage](https://gitlab.com/gitlab-org/govern/compliance/engineering/cis/gitlabcis/-/releases).\n\n\n```sh\n\npip install gitlabcis\n\n```\n\n\nThe scanner takes one positional argument (`URL`) and then options. The\nformat is: `gitlabcis URL OPTIONS`\n\n\n```sh\n\n# example: generate a json report\n\ngitlabcis \\\n    https://gitlab.example.com/path/to/project \\\n    -o results.json \\\n    -f json\n```\n\n\nThe full command line options can be found in [the\ndocumentation](https://gitlab.com/gitlab-org/govern/compliance/engineering/cis/gitlabcis/-/tree/main/docs?ref_type=heads#gitlabcis-usage).\n\n\n![GitLab CIS Benchmark\nscanner](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675788/Blog/Content%20Images/Screenshot_2024-10-26_at_8.16.22_AM.png)\n\n\n## gitlabcis scanner details\n\n\nThe team extracted all of the recommendation controls from the [CIS GitLab\nBenchmark](https://workbench.cisecurity.org/benchmarks/17538) and created\nthem in YAML to be used as [controls as\ncode](https://gitlab.com/gitlab-org/govern/compliance/engineering/cis/gitlabcis/-/tree/main/gitlabcis/recommendations?ref_type=heads).\n\n\nEach control has its own [dedicated\nfunction](https://gitlab.com/gitlab-org/govern/compliance/engineering/cis/gitlabcis/-/tree/main/gitlabcis/benchmarks?ref_type=heads)\nto enhance readability. This also allows an individual to observe how the\ncontrol performs its audit.\n\n\nAdditionally, certain control functions have limitations. We have identified\neach of these, which can be found in our [limitations\ndocument](https://gitlab.com/gitlab-org/govern/compliance/engineering/cis/gitlabcis/-/blob/main/docs/limitations.md?ref_type=heads).\n\n\nCurrently, the tool only accepts a _project URL_ input. It then only\nobserves configuration at a _project_ level. It does however support\nadministrative controls.\n\n\n* For example, the [1.1.2 - Code\nTracing](https://gitlab.com/gitlab-org/govern/compliance/engineering/cis/gitlabcis/-/blob/main/gitlabcis/recommendations/source_code_1/code_changes_1_1/code_tracing.yml)\ncontrol attempts to audit _\"... any change to code can be traced back to its\nassociated task\"_.\n    * This can be achieved with crosslinking issues in merge requests.\n    * Merge requests can be found at a project level, group level, or event instance level.\n    * The scanner currently only checks _at the project level_.\n* See [our roadmap](#gitlab-scanner-and-product-roadmap), which aims to\naddress this functionality gap.\n\n\n> Contribute to the [gitlabcis\nscanner](https://gitlab.com/gitlab-org/govern/compliance/engineering/cis/gitlabcis/)\nproject.\n\n\n## GitLab scanner and product roadmap\n\n\nThe creation of the scanner allowed us to contribute two features back into\nthe product with the help of the community.\n\n\n* [Show crosslinked/related issues in merge requests via the\nAPI](https://gitlab.com/gitlab-org/gitlab/-/issues/461536)\n\n* [Groups API: Add Restrict group access by\nDomain](https://gitlab.com/gitlab-org/gitlab/-/issues/351494)\n\n\nWe want to augment the scanner to be able to accept instances or groups as\ninput. For example, if you host GitLab at:\n[gitlab.example.com](http://gitlab.example.com), this could be used as an\ninput to check at the instance level if you are compliant against the CIS\nGitLab Benchmark and the same for groups.\n\n\nAdditionally, certain controls can be set at the instance or group level and\ntrickle down to the project level. There is work ongoing to include this\nfunctionality into the scanner. Check out the\n[epic](https://gitlab.com/groups/gitlab-org/govern/compliance/engineering/cis/-/epics/2)\nfor more information\n\n\nOne important aspect is incorporating [this functionality into the GitLab\nproduct itself](https://gitlab.com/groups/gitlab-org/-/epics/7854). The\nGitLab compliance team is working on [incorporating the CIS GitLab\nBenchmark](https://gitlab.com/groups/gitlab-org/-/epics/13823) and other\nstandards into the [Compliance Adherence\nReport](https://docs.gitlab.com/ee/user/compliance/compliance_center/). This\nwill allow customers real-time reviews of instances, groups, and projects\nacross a wide set of standards, not just CIS.\n\n\n> Learn more about the CIS GitLab Benchmark in our [public\nproject](https://gitlab.com/gitlab-org/govern/compliance/engineering/cis/gitlabcis).\n",[694,719,9],{"slug":3061,"featured":6,"template":698},"new-cis-gitlab-benchmark-scanner-boosts-security-and-compliance","content:en-us:blog:new-cis-gitlab-benchmark-scanner-boosts-security-and-compliance.yml","New Cis Gitlab Benchmark Scanner Boosts Security And Compliance","en-us/blog/new-cis-gitlab-benchmark-scanner-boosts-security-and-compliance.yml","en-us/blog/new-cis-gitlab-benchmark-scanner-boosts-security-and-compliance",{"_path":3067,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3068,"content":3073,"config":3079,"_id":3081,"_type":14,"title":3082,"_source":16,"_file":3083,"_stem":3084,"_extension":19},"/en-us/blog/new-report-on-ai-assisted-tools-points-to-rising-stakes-for-devsecops",{"title":3069,"description":3070,"ogTitle":3069,"ogDescription":3070,"noIndex":6,"ogImage":2763,"ogUrl":3071,"ogSiteName":686,"ogType":687,"canonicalUrls":3071,"schema":3072},"New report on AI-assisted tools points to rising stakes for DevSecOps","Read the key findings from the \"Omdia Market Radar: AI-Assisted Software Development, 2023-24\" report, including the state of AI-based code assistants.","https://about.gitlab.com/blog/new-report-on-ai-assisted-tools-points-to-rising-stakes-for-devsecops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"New report on AI-assisted tools points to rising stakes for DevSecOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Rusty Weston, Guest Contributor\"}],\n        \"datePublished\": \"2024-02-14\",\n      }",{"title":3069,"description":3070,"authors":3074,"heroImage":2763,"date":3076,"body":3077,"category":781,"tags":3078},[3075],"Rusty Weston, Guest Contributor","2024-02-14","Small wonder that the buzz about deploying generative AI and large language models (LLMs) for code completion and code generation has focused almost exclusively on developer productivity. It's a significant milestone — but it’s not the entire story. Less widely understood is what AI-assisted tools can do for development teams and, more broadly, for organizational competitiveness. Combining AI-powered tools and integrated development environments (IDEs) doesn’t just pump up developer efficiency, it transforms the entire software development lifecycle (SDLC) while adding “layers” of safety enhancements. \n\nDevSecOps teams see firsthand that AI-assisted software tools help reduce software testing bottlenecks and improve security as they streamline workflows. In this new era, DevSecOps can simultaneously shorten the software development cycle, enforce security standards, and enhance output. In short, the right tools make organizations more competitive. \n\nJust as LLM quality improvements amplify the value of generative AI, the new class of AI-powered development tools must offer privacy- and transparency- controls to harness these models effectively. Utilizing rigorous controls, DevSecOps gains efficiencies and improves team collaboration while reducing AI adoption's security and compliance risks.\n\n## An analyst take on what matters  \nOne of the key findings of a new report called “[Omdia Market Radar: AI-Assisted Software Development, 2023–24](https://learn.gitlab.com/devsecops-plat-ai/analyst-omdia-ai)” is that “the use of AI-based code assistants has reached a level of proficiency such that enterprises not using this technology will be at a disadvantage.”\n\n> [Read the Omdia Market Radar report](https://learn.gitlab.com/devsecops-plat-ai/analyst-omdia-ai). \n\nFew may have anticipated the development community’s swift integration of AI-powered application development. Until recently, it’s been a gradual build. According to Omdia, “The application of AI to code assistance has been ongoing for the last decade with a focus on assisting professional developers.” After years of development, the report emphasizes that “this technology is now a permanent part of the landscape.”\n\nOmdia’s finding also tracks with the [GitLab 2023 Global DevSecOps Report: The State of AI in Software Development](https://about.gitlab.com/developer-survey/), which featured input from 1,000 global leaders in development, IT operations, and security. Today, nearly one-in-four DevSecOps teams have adopted AI tools, and another two-thirds plan to use AI in software development. In the GitLab report, more than half (55%) of teams heralded the promise of improved efficiency. At the same time, two in five respondents expressed concerns about whether AI-generated code may introduce security vulnerabilities.\n\n## Advocating a layered approach \n\nGiven potential risks such as LLM inaccuracy,  including widely documented [hallucinations](https://www.fastcompany.com/91006321/how-ai-companies-are-trying-to-solve-the-llm-hallucination-problem), Omdia cautions brands that “careless use of LLM output could harm and tarnish” their reputation. “To increase the accuracy of this technology and ensure that developers can use this technology safely and without violating license rules in the data used to train the models, there is a need to add layers on top of the foundation model.”  \n\nBy layers, Omdia emphasizes the value of “safety and enhancement” safeguards and filters. These layers create a “major differentiator” for AI-assisted development tools because they manage “training data licensing rules, the quality and accuracy of the generated output, and the prevention of insecure code.” The report's authors caution that “generated outputs need to be carefully evaluated” to ensure they are “safe and of high quality.”\n\nIn effect, the safeguards and filters in AI-assisted software development establish a “defense-in-depth” strategy for coding. That’s a concept in which “[attacks missed by one technology are caught by another](https://csrc.nist.gov/glossary/term/defense_in_depth),” which can also apply to any elevated digital risk, such as reputational harm. \n\n## A new perspective on GitLab Duo\n\nOmdia highlighted [GitLab Duo](https://about.gitlab.com/gitlab-duo/), the company’s suite of AI capabilities, as one of the products it considers “suitable for enterprise-grade application development,” noting that its “AI assistance is integrated throughout the SDLC pipeline.” \n\nAmong the report highlights:\n- “GitLab places an emphasis on respecting user privacy and being transparent in how it operates. In its selection of AI technology, it is agnostic to the models adopted and will use what it considers the best model for each use case.”  \n- “When GitLab looked at where developers were spending their time, it was only 25% on coding, and 75% was taken up by other necessary tasks: planning, onboarding, testing, documentation, and security. Therefore, GitLab applies AI to all these tasks, not just code generation assistance.”\u2028\n- “To ensure privacy, GitLab does not let its AI retain user data in any way and does not use client code to train its models.”\n- GitLab’s AI gateway is model agnostic, and “GitLab uses models from Google and [Anthropic](https://about.gitlab.com/blog/gitlab-uses-anthropic-for-smart-safe-ai-assisted-code-generation/) to power GitLab Duo.”\u2028\n- Beyond code suggestions, developers “can ask Duo Explanation using natural language to explain what the code does.”\n\n## GitLab Duo introduces stronger controls\n\nFor DevSecOps teams, there’s no tradeoff between efficiency and security. Both are essential. GitLab Duo includes vital features such as Duo Code Suggestions and Chat, which enable AI-powered code completion, code generation, and chat, improving collaboration between developers, security, and operations teams. \n\nWith GitLab Duo, customer privacy is never subjected to tradeoffs. All customer code stays secret — it’s never applied to model training or fine-tuning. These practices are core to GitLab’s privacy- and transparency-first approach to team collaboration and security and reduce AI adoption's compliance risks. \n\nThe Omdia report notes that “software developers face greater complexity and hurdles today in producing code.” As a result, “There is a need to build in application security, including enforcing standards and triaging security vulnerabilities.” The report finds that GitLab has “security guardrails consistently applied throughout.” \n\nAdopters need tools that can help them tap AI’s benefits without introducing vulnerabilities or undermining compliance standards in ways that jeopardize trust with customers, partners, employees, and other critical stakeholders. DevSecOps teams seek tools to reduce the time, stress, and complexity of the entire application lifecycle.\n\n> [Read the Omdia Market Radar report](https://learn.gitlab.com/devsecops-plat-ai/analyst-omdia-ai).\n\n_Rusty Weston is an award-winning data-driven storyteller, editor, researcher, and writer. He formerly served as Editor of InformationWeek.com, Managing Editor at Yahoo!, and Vice President and Managing Editor for the Ogilvy content team._ \n",[717,9,994],{"slug":3080,"featured":91,"template":698},"new-report-on-ai-assisted-tools-points-to-rising-stakes-for-devsecops","content:en-us:blog:new-report-on-ai-assisted-tools-points-to-rising-stakes-for-devsecops.yml","New Report On Ai Assisted Tools Points To Rising Stakes For Devsecops","en-us/blog/new-report-on-ai-assisted-tools-points-to-rising-stakes-for-devsecops.yml","en-us/blog/new-report-on-ai-assisted-tools-points-to-rising-stakes-for-devsecops",{"_path":3086,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3087,"content":3092,"config":3097,"_id":3099,"_type":14,"title":3100,"_source":16,"_file":3101,"_stem":3102,"_extension":19},"/en-us/blog/oidc",{"title":3088,"description":3089,"ogTitle":3088,"ogDescription":3089,"noIndex":6,"ogImage":794,"ogUrl":3090,"ogSiteName":686,"ogType":687,"canonicalUrls":3090,"schema":3091},"Secure GitLab CI/CD workflows using OIDC JWT on a DevSecOps platform","Learn a new method to authenticate using JWT to increase the security of CI/CD workflows.","https://about.gitlab.com/blog/oidc","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Secure GitLab CI/CD workflows using OIDC JWT on a DevSecOps platform\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Dov Hershkovitch\"}],\n        \"datePublished\": \"2023-02-28\",\n      }",{"title":3088,"description":3089,"authors":3093,"heroImage":794,"date":3094,"body":3095,"category":10,"tags":3096},[1121],"2023-02-28","\n\nSecuring CI/CD workflows can be challenging. This blog post walks you through the problem validation, explores the JWT token technology and how it can be used with OIDC authentication, and discusses implementation challenges with authorization realms. You will learn about the current possibilities and future plans with GitLab 16.0. \n\n### Variables vs. secrets\nVariables are an efficient way to control and inject parameters into your jobs and pipelines, making managing and configuring the CI/CD workflows easier. You can read more about [how to use CI/CD variables](https://about.gitlab.com/blog/demystifying-ci-cd-variables/). An extra layer of security on top of variables to mask and protect, for now, is our “best-effort” to prevent sensitive variables from being accidentally revealed. However, variables are not a drop-in replacement for secrets. [Securing secrets natively](https://gitlab.com/gitlab-org/gitlab/-/issues/217355) is a solution that GitLab aspires to provide. Meanwhile, we recommend storing sensitive information in a dedicated secrets management solution. As a company, we will provide you abilities to integrate and retrieve secrets as part of your CI/CD workflows. \n\n## Security shifting left\nSensitive information like passwords, secret tokens, or shared IDs required to access tools and platforms need to be securely stored. They must also be highly available to their owners and the teams who use them. There are various secrets management solutions and frameworks available. They have addressed one problem but created new problems. For example: \"Which tool is right for our needs?\" More importantly, in software development: \"What's the best way to integrate this into our DevOps processes so that we're secure but still operating as efficiently as possible?\" Ignoring the security protocols in your organization is not an option. However, sensitive information should be stored as securely as possible. Something as simple as an access token stored in plain text can lead to security leaks and business incidents in the worst-case scenarios.\n\n## Initial support for JWT\nThe [JSON Web Token (JWT)](https://en.wikipedia.org/wiki/JSON_Web_Token) aims to build the integration bridge as an open standard for security claims exchange. It is a signed, short-lived, contextualized token that allows everyone to implement authentication between different products securely. The JWT consists of three parts: a header, a payload, and a signature.\n\n- The header represents the type of the token and the encryption algorithm.\n- The signature ensures that the token hasn't been altered.\n- The payload comprises a series of claims representing the information exchanged between two parties, which includes information about a GitLab user (ID, email, login) and the pipeline information (pipeline ID, job ID, environment, and more).\n\n_Example of GitLab JWT payload_\n\n```\n{\n  \"jti\": \"c82eeb0c-5c6f-4a33-abf5-4c474b92b558\",\n  \"iss\": \"gitlab.example.com\",\n  \"iat\": 1585710286,\n  \"nbf\": 1585798372,\n  \"exp\": 1585713886,\n  \"sub\": \"job_1212\",\n  \"namespace_id\": \"1\",\n  \"namespace_path\": \"mygroup\",\n  \"project_id\": \"22\",\n  \"project_path\": \"mygroup/myproject\",\n  \"user_id\": \"42\",\n  \"user_login\": \"myuser\",\n  \"user_email\": \"myuser@example.com\",\n  \"pipeline_id\": \"1212\",\n  \"pipeline_source\": \"web\",\n  \"job_id\": \"1212\",\n  \"ref\": \"auto-deploy-2020-04-01\",\n  \"ref_type\": \"branch\",\n  \"ref_protected\": \"true\",\n  \"environment\": \"production\",\n  \"environment_protected\": \"true\"\n}\n```\nUsing this information (called \"claims\"), you can implement an authentication condition where the token will get rejected if one of those claims does not match. You can use this to restrict access to only the authorized users and jobs in your pipelines.\n\nGitLab 12.10 added [initial support for JWT token-based connections](https://about.gitlab.com/releases/2020/04/22/gitlab-12-10-released/#retrieve-cicd-secrets-from-hashicorp-vault), which was later [enhanced](https://about.gitlab.com/releases/2020/09/22/gitlab-13-4-released/#use-hashicorp-vault-secrets-in-ci-jobs) with the `secrets:` keyword, as well as the `CI_JOB_JWT` predefined CI/CD variable, which is automatically injected into every job in a pipeline. This implementation was restricted to Hashicorp Vault, and users can use it to read secrets directly from the vault as part of their CI/CD workflow.\n \n### OIDC (JWT Version 2)\nThe logic we used to build the initial support for JWT opened up the possibility of connecting to other providers as well, but the first iteration was still restricted to Hashicorp Vault users.\n\nThis problem was addressed in GitLab 14.7 when we [released](https://about.gitlab.com/releases/2022/01/22/gitlab-14-7-released/#openid-connect-support-for-gitlab-cicd) the first \"Alpha\" version of JWT V2, which provided [Open ID Connect (OIDC)](https://openid.net/connect/) support for CI/CD.\n\nOIDC is an identity layer implemented on top of the JSON web token. You can securely authenticate against many products and services that implement OIDC, including AWS, GCP, and many more, making better use of the token's potential. Similar to our first JWT iteration, we added another [predefined CI/CD variable](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html) `CI_JOB_JWT_V2` which is also automatically injected into every job in a CI/CD pipeline.\n\n### Securely store your secrets \nYour software supply chain should include everything needed to deliver and run your software. Securing your supply chain means you need to secure your software and the surrounding (cloud-native) infrastructure. In [GitLab 15.9](https://about.gitlab.com/releases/2023/02/22/gitlab-15-9-released/), we've added additional layers of protection to move our OIDC token from an Experiment to General Availability, increasing the security of your CI/CD workflows. \n\n\n#### Opt-in JWT token\nJSON web tokens (V1 and V2) are stored in CI/CD variables, which are injected automatically into all jobs in a CI/CD pipeline. However, it is likely most jobs in your pipeline do not need the token. In addition to the inefficiency of injecting unused tokens into all jobs in a pipeline, there is a potential security vulnerability. All it takes is one compromised job for this token to be leaked and used by an attacker to retrieve sensitive information from your organization. To minimize this risk, we've added the ability to restrict the token variable from all jobs in your pipeline and expose it only to the specific jobs that need it.\n\nTo declare the JSON web token in a job that needs it, configure the job in the `.gitlab-ci.yml` configuration file following this example:\n\n```yaml\njob_name:\n  id_token:\n    MY_JOB_JWT: # or any other variable name\n  ...\n```\n\nYou can minimize the token exposure across your pipeline, but ensure it is available to the jobs that require it.\n\n#### Audience claim (`aud:`)\nClaims constitute the payload part of a JSON web token and represent a set of information exchanged between two parties. The JWT standard distinguishes between reserved, public, and private claims.\n\nThe audience (`aud:`) claim is a reserved claim, which identifies the audience that the JWT is intended for (the target of the token). In other words, which services, APIs, or products should accept this token. If the audience claim does not match, the token is rejected, so the audience claim is an essential part of software supply chain security.\n\nThe option to configure the audience claim is done in the CI/CD configuration when [declaring the usage of the JWT token](https://docs.gitlab.com/ee/ci/secrets/id_token_authentication.html#id-tokens), if we'll continue from the previous example:\n\n```yaml\njob_name:\n  id_token:\n    MY_JOB_JWT: # or any other variable name\n        aud: \"...\" # mandatory field\n  script:\n    - my-authentication-script.sh MY_JOB_JWT….. # use the declared variables in a script\n  ```\n\nConfiguring the audience claim is mandatory for Vault users that leverage the [GitLab/Vault native integration](https://docs.gitlab.com/ee/ci/secrets/#use-vault-secrets-in-a-ci-job) (using the 'secrets:' keyword).\n\n```yaml\njob_name:\n  secrets:\n    VAULT_JWT_1: # or any other variable name\n      id_token:\n        aud: 'devs' # audience claim configuration\n    STAGING_DATABASE_PASSWORD: # VAULT_JWT_1 is the token to be used\n      vault: staging/db/password@ops\n```\n\n### Breaking changes and backward compatibility \nWe understand the increasing demand to secure your software supply chain. We recognize that many of our current users already use the JWT in what will soon be the \"old JWT method\" (V1). To mitigate this conflict, we've decided that moving to the new (OIDC) JWT method is optional until the next major release (GitLab 16.0). To use the new (OIDC) token, users must opt-in to this change from the UI settings and update the pipeline configuration, as explained in the previous sections. Users can continue using the Experiment or the \"old method\" until GitLab 16.0. (At that point, only the \"new\" (OIDC) JWT token and method will be available.)\n\nSeveral breaking changes were announced for both [Vault users](https://docs.gitlab.com/ee/update/deprecations.html#hashicorp-vault-integration-will-no-longer-use-ci_job_jwt-by-default) and [users of the JWT \"old\" methods](https://docs.gitlab.com/ee/update/deprecations.html#old-versions-of-json-web-tokens-are-deprecated). Those changes are scheduled for GitLab 16.0.\n\n## Three ways to use the JWT token\nThere are three ways to use a JWT to authenticate against different products in your CI/CD pipeline:\n- The \"old\" method, using the `secrets:` keyword and the `CI_JOB_JWT` variable, which is mainly used to integrate with Hashicorp Vault.\n- An \"Alpha\" version that uses the `CI_JOB_JWT_V2` OIDC token to integrate with different cloud providers.\n- A production-ready OIDC token, which is a secured version of the `CI_JOB_JWT_V2` token, used to authenticate with a variety of different products, like Vault, GCP, AWS, and so on.\n\nAll three methods are available until the next major version (GitLab 16.0). At that point, only the secured OIDC token will be available.\n\nTo prepare for this change, you should:\n\n1. Configure your pipelines to use the fully configurable and more secure [id_token](https://docs.gitlab.com/ee/ci/yaml/index.html#id_tokens) keyword.\n2. Enable the [Limit JSON Web Token (JWT) access setting](https://docs.gitlab.com/ee/ci/secrets/id_token_authentication.html#enable-automatic-id-token-authentication), which prevents the old tokens from being exposed to any jobs. (This setting will be permanently enabled for all projects in GitLab 16.0).\n3. If you use GitLab/Hashicorp native integration (using the [secrets:vault](https://docs.gitlab.com/ee/ci/yaml/#secretsvault) keyword), ensure the bound audience is prefixed with `https://`.\n\nThis should ensure a smooth transition to [GitLab 16.0](/upcoming-releases/) without breaking your existing workflows.\n\n\n",[827,9,825,826],{"slug":3098,"featured":6,"template":698},"oidc","content:en-us:blog:oidc.yml","Oidc","en-us/blog/oidc.yml","en-us/blog/oidc",{"_path":3104,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3105,"content":3111,"config":3116,"_id":3118,"_type":14,"title":3119,"_source":16,"_file":3120,"_stem":3121,"_extension":19},"/en-us/blog/one-devops-platform-can-help-you-achieve-devsecops",{"title":3106,"description":3107,"ogTitle":3106,"ogDescription":3107,"noIndex":6,"ogImage":3108,"ogUrl":3109,"ogSiteName":686,"ogType":687,"canonicalUrls":3109,"schema":3110},"One DevOps platform can help you achieve DevSecOps","GitLab drives innovation in the AST market to secure cloud-native applications.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679348/Blog/Hero%20Images/locks.jpg","https://about.gitlab.com/blog/one-devops-platform-can-help-you-achieve-devsecops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"One DevOps platform can help you achieve DevSecOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sandra Gittlen\"}],\n        \"datePublished\": \"2022-05-09\",\n      }",{"title":3106,"description":3107,"authors":3112,"heroImage":3108,"date":3113,"body":3114,"category":694,"tags":3115},[799],"2022-05-09","\n\nApplication security testing (AST) is a fast-moving and important area for software development. DevOps methodologies have spurred the need to integrate testing within the developer’s workflow. GitLab believes the more ingrained AST is in the software factory, the more secure applications will be and the easier it will be for companies to meet compliance demands. We believe our [strategic platform approach](/why-gitlab), where security and compliance are embedded in DevOps from planning to production, provides efficiency and value unmatched by traditional application security vendors.\n\nGartner® has named GitLab a Challenger in the [2022 Gartner Magic Quadrant™ for Application Security Testing](https://page.gitlab.com/resources-report-gartner-magic-quadrant-ast.html). According to Gartner, “a major driver for the evolution of the AST market is the need to support enterprise [DevSecOps](/topics/devsecops/) and cloud-native application initiatives.”\n\n“We are excited to see continued momentum for our unique approach that embeds security into the DevOps workflow,” says Hillary Benson, GitLab director of product management. This is the third year that GitLab has been recognized in the Gartner Magic Quadrant for Application Security Testing. “We believe that our recognition as a Challenger in the Magic Quadrant represents an evolving market understanding of the value of an approach that empowers and enables developers to find and fix vulnerabilities – and the simplicity of leveraging a DevOps platform to do so.”\n\n> **You can read more about the results and download a copy of the report by visiting [our commentary page](/analysts/gartner-ast22/).**\n\n\nGitLab’s complete DevOps platform approach provides automation needed by DevOps, along with policy and vulnerability management needed by security professionals. GitLab’s Ultimate tier provides an integrated, vetted, and managed set of scanners to meet the security and compliance needs of modern-day application development and [cloud-native](/topics/cloud-native/) environments. \n\n## A unique approach to AST\n\nWe continue to innovate in the application security space. Let’s look at how we’re different from many of the more traditional stand-alone AST technologies. It’s these very differences that provide benefits achievable by using a single platform for DevOps and security. For example: \n\nWe build comprehensive scans into the CI pipeline to enable a more interactive testing environment. This is a unique approach as others in the category focus their offering on instrumentation-based interactive AST. With GitLab, the developer gets a more complete view of the security flaws as they are created – when they are most efficiently resolved.\n\nSimilarly, while analysts place emphasis on lightweight spell-check-like SAST features, we have found that these features are less important to GitLab users, again because of our built-in approach. A metaphor may be helpful to explain. We are all accustomed to saving documents frequently so edits are not lost. Developers do the same while editing software. Changes made are “committed” frequently to the code repository. Upon hitting the ‘commit’ button, GitLab performs a true, [SAST scan](/direction/secure/static-analysis/sast/) on code changes, which gives developers instant and more complete feedback. And DevOps teams can choose to enable  [DAST scanning](https://docs.gitlab.com/ee/user/application_security/dast/) that uses GitLab’s review app feature to assess changes pre-merge. Similarly,  [dependencies](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/), containers, infrastructure as code, and more can all be scanned, at the push of the commit button.\n\nIn addition, GitLab also is keen on providing DevOps teams just-in-time education about vulnerabilities and fixes. Now, via partnerships with [Kontra](/blog/kontra-and-gitlab-integrate-vulnerability-education-into-the-devops-workflow/) and [Secure Code Warrior](/blog/heres-how-to-get-integrated-secure-coding-advice-in-gitlab/), GitLab provides developers with crisp training on how to mitigate the specific vulnerability they just created. This helps developers learn proper coding techniques instead of flagging the problem to figure out later.\n\n## Concentrating on compliance\n\nShifting compliance left and embedding it deep into the software development lifecycle, a.k.a. [continuous software compliance](/solutions/compliance/), is also a priority for GitLab.\n\n“We enable organizations to create policies that align with their compliance regulations and enforce them throughout the application development workflow,” Benson says. “Rather than juggling multiple policy enforcement applications, you have a single lens for visibility across the entire lifecycle.” For instance, a company can develop granular compliance pipeline policies that require a SAST to run for every commit in a certain project or a chain of MR approvals that developers can’t circumvent. “Those types of common controls and separation of duties simplify software audits and speed up application deployments.”\n\nGitLab is honored to be recognized in the Gartner Magic Quadrant, and will continue to empower and unite developers and security professionals alike using repeatable, defensible processes that automate security and compliance policies from development through production.\n\n> **[Start a free Ultimate trial](https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial)**\n \n_Gartner, “Magic Quadrant for Application Security Testing,” Dale Gardner, Mark Horvath, Dionisio Zumerle, April 18, 2022. Gartner does not endorse any vendor, product or service depicted in our research publications, and does not advise technology users to select only those vendors with the highest ratings or other designation. Gartner research publications consist of the opinions of Gartner's research organization and should not be construed as statements of fact. Gartner disclaims all warranties, expressed or implied, with respect to this research, including any warranties of merchantability or fitness for a particular purpose. GARTNER and Magic Quadrant are registered trademarks and service marks of Gartner, Inc. and/or its affiliates in the U.S. and internationally and are used herein with permission. All rights reserved._\n\nCover image by [Fly:D](https://unsplash.com/photos/ZNOxwCEj5mw) on Unsplash\n{: .note}\n",[1299,9,2040,694,1198],{"slug":3117,"featured":6,"template":698},"one-devops-platform-can-help-you-achieve-devsecops","content:en-us:blog:one-devops-platform-can-help-you-achieve-devsecops.yml","One Devops Platform Can Help You Achieve Devsecops","en-us/blog/one-devops-platform-can-help-you-achieve-devsecops.yml","en-us/blog/one-devops-platform-can-help-you-achieve-devsecops",{"_path":3123,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3124,"content":3130,"config":3135,"_id":3137,"_type":14,"title":3138,"_source":16,"_file":3139,"_stem":3140,"_extension":19},"/en-us/blog/origin-of-devsecops-platform-category",{"title":3125,"description":3126,"ogTitle":3125,"ogDescription":3126,"noIndex":6,"ogImage":3127,"ogUrl":3128,"ogSiteName":686,"ogType":687,"canonicalUrls":3128,"schema":3129},"Disagree, commit, and disagree: How a lazy solution became a category","Find out the origin story of the DevSecOps category.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679881/Blog/Hero%20Images/flowercomingthroughsidewalkcrack.png","https://about.gitlab.com/blog/origin-of-devsecops-platform-category","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Disagree, commit, and disagree: How a lazy solution became a category\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sid Sijbrandij\"}],\n        \"datePublished\": \"2023-08-30\",\n      }",{"title":3125,"description":3126,"authors":3131,"heroImage":3127,"date":3132,"body":3133,"category":994,"tags":3134},[1731],"2023-08-30","\nA few months ago, GitLab - and the DevOps Platform category - reached a big milestone. Two influential analyst firms, [Gartner](https://about.gitlab.com/blog/gitlab-leader-gartner-magic-quadrant-devops-platforms/) and [Forrester](https://about.gitlab.com/blog/gitlab-leader-forrester-wave-integrated-software-delivery-platforms/), issued reports that validate the market is moving from point solutions to a platform. They officially recognized DevOps platforms as a category. A category we created. \n\nThis is the story of how we did it.\n\nI am thrilled that we created a category. Very few companies are able to do so. Other examples are Dropbox for the file hosting service category; Hubspot for inbound marketing; and Slack for searchable logs of all communications and knowledge. The backstory is that we did not start with a vision for creating a category. GitLab didn’t even begin as a business. It started with a programmer’s need for a great open source collaboration tool. \n\nNow, nearly 12 years after GitLab’s [very first commit](https://gitlab.com/gitlab-org/gitlab-foss/-/commit/9ba1224867665844b117fa037e1465bb706b3685), I want to share what we learned on the journey to creating the DevOps Platform category.\n\n## Category design begins with solving your own problem\nDmitriy Zaporozhets needed a tool to collaborate with his team. His employer at the time wasn’t willing to buy the tool he wanted, so he decided to build it himself. He created GitLab in 2011 from his home in Ukraine.\n\nTogether with Valeriy Sizov, Dmitriy started to build GitLab as a developer collaboration tool based on Git. Developers from around the world quickly began using it. In the first year, 300 people contributed to improving it.\n\nGitLab was not founded with a grand plan or a 10-year vision to create a single platform for the entire software development lifecycle. The reality is that GitLab began with one person who had a need and built a solution to meet it.\n\n## Categories are discovered, not planned\nOne of the things I respect most about Dmitriy is that he built GitLab as open source, allowing others to use his ideas and build on them in their own ways. He was so committed to open source that he was supportive of me commercializing his work.\n\nI encountered GitLab for the first time in 2012. I recognized the value that it could provide for other software companies, but I also saw the challenges in installing and managing it. Not everyone had the means to do that. I saw the potential for GitLab to be commercialized as a SaaS business: cloud-based source code management (SCM) for everyone.\n\nI was nervous about commercializing Dmitriy’s work, so I reached out to tell him what I was working on. He was happy that what I was doing could help GitLab become more popular and attract even more community contributions, which it did.\n\nThis was our exchange: \n\n\n![Emails between Sid and Dmitriy](https://about.gitlab.com/images/blogimages/devsecopsoriginmessages.png){: .shadow}\n\n\nIn late 2012, similar to how Dmitriy made an SCM tool for his own need, he built his own continuous integration (CI) tool called GitLab CI, a tool that ran tests to check the code for conflicts.\n\nMeanwhile, large organizations began adopting GitLab, and Dmitriy tweeted that he wanted to work on GitLab full-time. I got in touch with him to work out an arrangement for him to join GitLab, the company. But when I went to the local Western Union branch to make a wire transfer, I had to convince the teller that I knew Dmitriy and was not falling victim to wire transfer fraud - a common issue at the time.\n\nWe then introduced [GitLab Enterprise Edition](https://about.gitlab.com/releases/2013/07/22/announcing-gitlab-enterprise-edition/) with features asked for by larger organizations. \n\nThen, in 2015, we noticed that a community contributor named Kamil Trzciński built a far better runner than we did (ours was in Ruby and single-threaded, his was in Go and multi-threaded). It was so much better that we decided to adopt his runner as the standard.\n\nThrough iteration, building on each other’s ideas, and being open to ideas from outside our company, we continued to build two great tools for SCM and CI. \n\nHowever, I admit that there were critical moments when our willingness to allow others to contribute would be tested. When Kamil joined GitLab full-time we could not have predicted that he would help us discover a new category. Not by contributing a better CI runner but by changing the way software is developed. \n\nKamil suggested a radical idea: to integrate GitLab SCM and GitLab CI into one tool.\n\n## Disagree, commit, and disagree\nDmitriy and I disagreed with Kamil. Dmitriy believed in the Unix philosophy where one program should do one thing well; if you want a program to do something else, start a new one. I thought that customers wanted separate tools for separate use cases. The market was filled with specialized point solutions.\n\nMany business leaders say, “Disagree and commit,” and we did. We disagreed, and committed to continuing to build two different products.\n\nBut Kamil persisted in making a strong case for [why SCM and CI should be integrated](https://about.gitlab.com/blog/gitlab-hero-devops-platform/). This is when our operating principle of [disagree, commit, and disagree](https://handbook.gitlab.com/handbook/values/#disagree-commit-and-disagree) was born. Every decision can be changed, and the best decisions should often be made despite management’s opinion.\n\nDmitry and I relented and took Kamil’s suggestion over our opinion and the opinion of the market. \n\nIt was a lazy choice because combining SCM and CI would mean having only one Ruby on Rails app to maintain. We could avoid duplicating the interface and the data, making it more efficient to develop code. But it also ended up being a far better user experience, giving customers a much faster way to set up CI, and faster cycle times by not having to switch between apps. GitLab became a platform with one UI, one data store, one way to serve up information, and one way for a company to collaborate and be on the same page at the same time.\n\nBy taking the suggestion of someone new to the team and creating [the world’s first DevOps platform](https://about.gitlab.com/blog/how-ten-steps-over-ten-years-led-to-the-devops-platform/), we changed the course of our company and, eventually, the whole software development industry. I am proud to be a part of the DevSecOps Platform story because it is a story about allowing everyone to contribute, especially when someone else has the best idea. \n\nIt is important to disagree and commit but still disagree. That is how Dmitriy and I realized that there could be one platform for the entire software development lifecycle, and eight years later, Forrester, Gartner, and the market see it, too.\n\nToday, we have a [DevSecOps platform](https://about.gitlab.com/platform/?stage=plan). \n\nLooking to the future, we hope to create another category: [AllOps](https://about.gitlab.com/company/vision/), a single application, for all R&D that includes DevSecOps, ModelOps DataOps, and Service Desk. \n\nIn the future, we will expand support for [ModelOps and DataOps](https://about.gitlab.com/direction/modelops/) to give customers the ability to manage data and its associated AI/ML models in a similar fashion to their software projects. \n\nAnd, because customers need the ability to triage application incidents directly where their applications are built and deployed, we will continue to expand our [Service Desk](https://docs.gitlab.com/ee/user/project/service_desk/index.html) offering.\n\nIt is GitLab’s mission to ensure that everyone can contribute. Our vision for AllOps moves us further in that direction - to deliver a single application for all innovation.\n",[994,1038,496,9],{"slug":3136,"featured":6,"template":698},"origin-of-devsecops-platform-category","content:en-us:blog:origin-of-devsecops-platform-category.yml","Origin Of Devsecops Platform Category","en-us/blog/origin-of-devsecops-platform-category.yml","en-us/blog/origin-of-devsecops-platform-category",{"_path":3142,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3143,"content":3149,"config":3155,"_id":3157,"_type":14,"title":3158,"_source":16,"_file":3159,"_stem":3160,"_extension":19},"/en-us/blog/our-step-by-step-guide-to-evaluating-runtime-security-tools",{"title":3144,"description":3145,"ogTitle":3144,"ogDescription":3145,"noIndex":6,"ogImage":3146,"ogUrl":3147,"ogSiteName":686,"ogType":687,"canonicalUrls":3147,"schema":3148},"Our step-by-step guide to evaluating runtime security tools","Key learnings from the GitLab Security team’s runtime security tool evaluation on Kubernetes clusters and Linux servers using real-world attack simulations.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097534/Blog/Hero%20Images/Blog/Hero%20Images/AdobeStock_1097303277_6gTk7M1DNx0tFuovupVFB1_1750097534344.jpg","https://about.gitlab.com/blog/our-step-by-step-guide-to-evaluating-runtime-security-tools","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Our step-by-step guide to evaluating runtime security tools\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Hiroki Suezawa\"},{\"@type\":\"Person\",\"name\":\"Mitra Jozenazemian\"}],\n        \"datePublished\": \"2025-05-13\",\n      }",{"title":3144,"description":3145,"authors":3150,"heroImage":3146,"date":3152,"body":3153,"category":694,"tags":3154},[3151,927],"Hiroki Suezawa","2025-05-13","Choosing the right runtime security tool is critical for protecting modern cloud-native environments.  We recently undertook a rigorous evaluation process using real-world attack simulations on our Kubernetes clusters and Linux servers. Why? Because traditional cloud audit logs do not provide enough detail, leaving critical gaps in threat detection, incident response, and forensic analysis. Our evaluation meticulously examined each critical stage from initial access to lateral movement and data exfiltration.\n\nWhile we won't be naming the specific vendor in this post, we want to share our detailed methodology and key learnings, providing a blueprint you can adapt for your own security tool evaluations.\n\n## Why are runtime security tools necessary?\n\nWithout runtime security tools, detecting “suspicious activities” and understanding “what actually happened” during an attack can become extremely challenging.\n\n### Limitations of cloud audit logs\n\n- **Lack of runtime details**  \n  Cloud audit logs primarily record operations and data access within the cloud. However, they do not capture runtime-level activities on systems such as Kubernetes servers – overlooking fine-grained command executions, process behaviors, and transient network activities.  \n\n- **Gaps in investigation and forensics**  \n    In Kubernetes environments, the absence of continuous, real-time logging can lead to the loss of critical activity records once a container terminates.\n\nAlthough well-known open-source runtime security tools are available, we decided to evaluate a commercial product to assess additional capabilities and enterprise-level support through attack simulation testing.\n\n### The role and purpose of runtime security tools\n\nRuntime security tools address these cloud audit log limitations by continuously monitoring systems in real time, offering the following functionalities:\n\n- **Threat detection**  \n  They monitor command executions, system calls, and network events in real-time to instantly detect abnormal behaviors, which enables the security team to respond rapidly. While some public cloud providers now offer limited runtime monitoring capabilities, these native solutions typically lack the depth and comprehensive coverage of dedicated security tools.  \n\n- **Incident response**  \n  By maintaining detailed chronological records of system activities, these tools provide security teams with the evidence needed to reconstruct attack timelines, determine the full scope of compromise, and conduct thorough forensic investigations after an incident occurs.  \n\n- **Scalability in investigations**  \n  Unlike traditional endpoint-by-endpoint forensic analysis, runtime security tools allow teams to collect, store, and analyze data centrally across the entire environment. This enables the efficient investigation of incidents without manually correlating disparate data sources.  \n\n(**Note:** Products that also offer container information or server vulnerability monitoring are outside the scope of this discussion.)\n\n## Key evaluation points\n\nOur primary objective in evaluating a runtime security tool was to determine its effectiveness in real-world security investigations. While evaluations often focus on the volume of detections or overall coverage, in actual operations, an overload of false positives – or tens of alerts for a single attack chain – can paralyze incident response teams. Therefore, our in-depth investigation centered on whether the tool could be used to support security operations with understanding and responding to actual attacks.\n\n- **Detection capability**  \n\n  - **Built-in rule**  \n    We assessed whether the built-in rule sets could effectively detect a variety of attack techniques and provide the necessary detail for accurate detection.\n\n  - **Custom detection capabilities**  \n    We evaluated the ease with which additional rules could be integrated and considered the quality of telemetry data delivered by the product, which enabled us to build our own monitoring solutions leveraging our unique understanding of our environment.\n\n  - **Alert quality**  \n    We also verified the rate of false positives. We confirmed that it effectively focuses on genuine security threats requiring action while minimizing noise that could cause alert fatigue.\n\n- **Incident response**  \n\n  - **Richness of logs**  \n    We evaluated whether the logs capture sufficient details – including executed commands, network connections, DNS queries, and process information – to fully reconstruct the incident. The ability to piece together the entire attack scenario and determine the full impact is crucial during incident response.  \n\n  - **Log searchability**  \n    We assessed how effectively the tool allowed us to search, filter, and correlate events across multiple systems. The ability to quickly query massive volumes of data is essential for timely investigations during security incidents. \n\n## Evaluation process\n\nWe divided our evaluation process into four major phases:\n\n1. **Development of attack scenarios**  \n   We designed scenarios that mimicked real-world attack flows. These scenarios, developed in collaboration with our Red Team, included the following elements:  \n   - attacks exploiting GitLab-specific vulnerabilities (e.g., CVE-2021-22205)  \n   - attacks leveraging the compromise of developer laptops  \n   - detailed step-by-step attack procedures  \n2. **Infrastructure setup**  \n   We deployed two parallel environments:  \n   - Kubernetes environment  \n   - Virtual machine (VM) environment \n\n   We installed an older version of GitLab to test known vulnerabilities and carried out similar evaluation flows in both the Kubernetes and VM environments.\n\n3. **Execution of attacks**  \n   We executed the attack flow for each scenario and meticulously recorded the timeline – from initial access to lateral movement and data exfiltration.  \n\n4. **Analysis of results**  \n   We conducted a comprehensive evaluation of detection capabilities, log richness, and areas for improvement, clearly outlining the strengths and weaknesses of the tools.\n\n### Attack scenarios\n\n**Scenario 1: Exploitation of a known GitLab vulnerability**\n\n![Scenario 1: Exploitation of a known GitLab vulnerability](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097560/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750097560795.png)\n\n- **Attack flow**  \n  1. **Initial access**  \n     We simulated an attack by exploiting CVE-2021-22205, a known GitLab vulnerability that allows remote code execution. This granted us unauthorized access to the target system.  \n  2. **Command execution**  \n     After gaining access, we executed a reverse shell to interact remotely with the compromised machine and take control.  \n  3. **Deployment of a C2 agent**  \n     We installed a Command and Control (C2) agent to evaluate persistence techniques, enabling us to execute further commands and manage the system remotely.  \n  4. **Lateral movement**  \n     We then moved laterally within the environment, accessing Kubernetes API secrets and PostgreSQL databases.  \n  5. **Data exfiltration**  \n     We exfiltrated sensitive data via a dedicated C2 channel.\n\nThe following table summarizes the attack techniques used at each phase:\n\n| Initial access | Command and control | Enumeration | Credential access | Lateral movement | Collection | Exfiltration |\n| :---- | :---- | :---- | :---- | :---- | :---- | :---- |\n| Exploit GitLab application using known RCE vulnerability | Execute known reverse shell command | Harvesting info on the box | Get environment variables | Get secret from Kubernetes API | Get data from Cloud Storage | Exfiltration over C2 channel |\n|  | Install post-exploitation C2 agent |  | Get K8s token | Access to database | DNS exfiltration |  |\n|  | SOCKS proxy |  | Get cloud token via Cloud metadata server |  |  |  |\n\n\u003Cbr>\u003C/br>\n\n**Scenario 2: Compromise of a developer’s laptop**\n\n![Scenario 2: Compromise of a developer’s laptop](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097561/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750097560796.png)\n\n- **Attack flow**  \n  1. **Initial compromise**   \n     We simulated an attacker compromising a developer’s laptop and abusing legitimate credentials to gain unauthorized access to internal resources.  \n  2. **Privilege escalation**  \n     Using the compromised credentials, we escalated privileges within the Kubernetes environment. \n  3. **Container manipulation**  \n     We deployed a privileged container to extract sensitive information.  \n  4. **Data exfiltration and persistence**  \n     We exfiltrated sensitive data while maintaining persistent access.\n\n      The following table summarizes the attack techniques used at each phase:\n\n| Initial access | Execution | Privilege escalation | Credential access | Lateral movement | Exfiltration |\n| :---- | :---- | :---- | :---- | :---- | :---- |\n| Valid account (kubectl) | Create a new container | Create a privileged container | Get K8s secrets via privilege of the node | Enter a container in the same node | Upload credential data to the attacker’s server |\n|  |  |  | Get an environment variable in the containers via `crictl` command on the node |  |  |\n\n\u003Cbr>\u003C/br>\n\n### Execution of the attacks\nDuring the execution of the attack scenarios, we followed these processes to obtain detailed records:\n\n- **Verification of detections:** We confirmed whether each attack command was detected and if the key points of each scenario were properly flagged.\n\n- **Timeline recording:** Every event was logged in sequence to assess how well command executions and network communications were captured.\n\n- **Scoring and analysis:** We scored each event based on detection effectiveness to quantitatively evaluate the tool’s performance.\n\n## What we learned\n\n### Don't overestimate – test commercial products yourself\n\n- **Identifying and addressing detection gaps (collaboration with vendors)**  \n  Our evaluation revealed that several critical scenarios and events were not detected or not logged. Consequently, we held meetings with the vendor and submitted multiple improvement requests. As a result, the vendor enhanced the product by adding new features and improving detection capabilities, with many issues identified during our evaluation subsequently addressed.  \n- **Understanding the limitations**  \n  Many modern runtime security tools use eBPF to monitor Linux system calls for detection. However, because commands executed within a C2 framework do not generate new processes, tracing these attack events proved challenging.  \n\n- **Recognizing tool boundaries**  \n  Our findings highlighted that, during incident response, relying solely on runtime security tools is insufficient. It is essential to combine them with other logs, such as Kubernetes audit logs and cloud logs, to gain a comprehensive view.\n\n### The importance of continuous runtime event logging in Kubernetes\n\nIn Kubernetes environments, there is a risk of losing forensic data when containers terminate, making continuous logging indispensable. Our evaluation confirmed that establishing a scalable, persistent logging infrastructure is crucial. Without proper runtime security tools, a significant amount of critical information could be lost post-attack.\n\n## Summary\n\nWe do not simply install security tools – we evaluate their utility to help ensure that our customers can safely use GitLab.com. Thorough product assessments like the one outlined above not only reveal unique use cases and areas for improvement that vendors might overlooks, but also provide valuable insights that benefit both the vendor and internal teams in organizing how the tool is best utilized.\n",[694,9,1038],{"slug":3156,"featured":6,"template":698},"our-step-by-step-guide-to-evaluating-runtime-security-tools","content:en-us:blog:our-step-by-step-guide-to-evaluating-runtime-security-tools.yml","Our Step By Step Guide To Evaluating Runtime Security Tools","en-us/blog/our-step-by-step-guide-to-evaluating-runtime-security-tools.yml","en-us/blog/our-step-by-step-guide-to-evaluating-runtime-security-tools",{"_path":3162,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3163,"content":3169,"config":3175,"_id":3177,"_type":14,"title":3178,"_source":16,"_file":3179,"_stem":3180,"_extension":19},"/en-us/blog/oxeye-joins-gitlab-to-advance-application-security-capabilities",{"title":3164,"description":3165,"ogTitle":3164,"ogDescription":3165,"noIndex":6,"ogImage":3166,"ogUrl":3167,"ogSiteName":686,"ogType":687,"canonicalUrls":3167,"schema":3168},"Oxeye joins GitLab to advance application security capabilities ","The initial focus will be on accelerating GitLab's Static Application Security (SAST) roadmap.\n","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749671969/Blog/Hero%20Images/gitlab-oxeye-blog-1800x945.png","https://about.gitlab.com/blog/oxeye-joins-gitlab-to-advance-application-security-capabilities","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Oxeye joins GitLab to advance application security capabilities \",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David DeSanto, Chief Product Officer, GitLab\"},{\"@type\":\"Person\",\"name\":\"Dean Agron, co-founder and CEO, Oxeye\"}],\n        \"datePublished\": \"2024-03-20\",\n      }",{"title":3164,"description":3165,"authors":3170,"heroImage":3166,"date":3172,"body":3173,"category":994,"tags":3174},[1905,3171],"Dean Agron, co-founder and CEO, Oxeye","2024-03-20","GitLab has acquired [Oxeye](https://www.oxeye.io/) to advance GitLab’s application security capabilities with an initial focus on accelerating its Static Application Security Testing (SAST) roadmap. \n\nGitLab first launched SAST in 2017. We have since continued to mature our application security capabilities as part of our vision to evolve SAST as a key part of the GitLab DevSecOps workflow. This not only means enhancing our best-in-class offering with advances in AI/ML but also reinforcing the power of SAST across the entire software development lifecycle by continuously improving the signal-to-noise ratio, reducing false positives that commonly plague SAST solutions. \n\nFor SAST to have the most impact on security, it must be used seamlessly with other security and development tools and accessible to developers. SAST is a powerful tool, but it loses much of its value if the results are unmanageable or lack appropriate context.\n\nGitLab is the most comprehensive AI-powered DevSecOps platform combining security natively with source control, build tools, repositories, and other features like issue tracking and application monitoring. Our approach to innovating in static analysis combines our focus on open source, our platform approach, and specialized investments in SAST.\n\nGitLab has a history of innovation in the SAST space:\n- We were early to include SAST in a DevOps platform in 2017.\n- We were the first DevSecOps platform to be recognized in the 2020 Gartner® Magic Quadrant™ for Application Security Testing. \n- We contribute heavily to open source SAST tools.\n\nRecently, Forrester recognized GitLab as the only Leader in [The Forrester Wave™: Integrated Software Delivery Platforms, Q2 2023](https://about.gitlab.com/blog/gitlab-leader-forrester-wave-integrated-software-delivery-platforms/). The report included a customer’s comment on the platform, noting that “The CI/CD experience using secrets, environments, runners, and SAST/DAST/license scans/etc. is unparalleled.” \n\nAcquiring Oxeye for best-in-class scanning technology is another step toward accelerating GitLab’s SAST roadmap. Its enhanced SAST scanner will streamline vulnerability management and remediation for developers. Empowering developers to have an impact on the security of their products requires security findings to be accurate and focused on the most critical and exploitable weaknesses. Oxeye’s capabilities will help GitLab to realize that vision. \n\nOxeye’s capabilities beyond SAST include the ability to trace vulnerabilities from “code to cloud” by providing runtime context via different types of data collection and analysis. We anticipate enhancing our software composition analysis and compliance tools with these capabilities to further help our customers identify and resolve all application-layer risks quickly.\n\nThe combined strength and security expertise of the GitLab and Oxeye teams will help even more organizations reduce their security and compliance risk as they accelerate their digital transformation efforts.\n\n> [Learn more about GitLab SAST](https://about.gitlab.com/solutions/security-compliance/) and other application security capabilities.",[694,994,9],{"slug":3176,"featured":91,"template":698},"oxeye-joins-gitlab-to-advance-application-security-capabilities","content:en-us:blog:oxeye-joins-gitlab-to-advance-application-security-capabilities.yml","Oxeye Joins Gitlab To Advance Application Security Capabilities","en-us/blog/oxeye-joins-gitlab-to-advance-application-security-capabilities.yml","en-us/blog/oxeye-joins-gitlab-to-advance-application-security-capabilities",{"_path":3182,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3183,"content":3189,"config":3195,"_id":3197,"_type":14,"title":3198,"_source":16,"_file":3199,"_stem":3200,"_extension":19},"/en-us/blog/quick-setup-of-a-gke-cluster-with-argocd-pre-installed-using-terraform",{"title":3184,"description":3185,"ogTitle":3184,"ogDescription":3185,"noIndex":6,"ogImage":3186,"ogUrl":3187,"ogSiteName":686,"ogType":687,"canonicalUrls":3187,"schema":3188},"Quick setup of a GKE Cluster with ArgoCD pre-installed using Terraform","Use this tutorial as a great starting point to manage your cluster entirely through GitOps.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665989/Blog/Hero%20Images/AdobeStock_618473457.jpg","https://about.gitlab.com/blog/quick-setup-of-a-gke-cluster-with-argocd-pre-installed-using-terraform","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Quick setup of a GKE Cluster with ArgoCD pre-installed using Terraform\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Noah Ing\"},{\"@type\":\"Person\",\"name\":\"Siddharth Mathur\"}],\n        \"datePublished\": \"2024-01-31\",\n      }",{"title":3184,"description":3185,"authors":3190,"heroImage":3186,"date":3191,"body":3192,"category":909,"tags":3193},[821,906],"2024-01-31","This tutorial will walk you through setting up a Google Kubernetes Engine\n(GKE) Cluster with ArgoCD pre-installed, utilizing Terraform, in less than\n10 minutes. This will be a great starting point to manage your cluster\nentirely through GitOps.\n\n\n### Prerequisites\n\n- GCP account with permissions to provision a GKE Cluster\n\n- Kubectl client v1.23.9\n\n- Kubectl server v1.23.16-gke.1400\n\n- Working knowledge of GKE\n\n- Basic knowledge of ArgoCD\n\n\n#### An overview of this tutorial is as follows:\n\n- Set up the GitLab Terraform GKE ArgoCD Template \n\n- Connect to your GKE Cluster\n\n- Grab the ArgoCD Initial Admin Secret\n\n- Log into ArgoCD \n\n- Enjoy your Kubernetes Cluster with ArgoCD!\n\n\n#### Set up the GitLab Terraform GKE ArgoCD template\n\n\nStart by importing the example project by URL -\n[https://gitlab.com/projects/new#import_project](https://gitlab.com/projects/new#import_project).\n\n\nTo import the project:\n\n1. In GitLab, on the top bar, select **Main menu > Projects > View all\nprojects**.\n\n2. On the right of the page, select **New project**.\n\n3. Select **Import project**.\n\n4. Select **Repository by URL**.\n\n5. For the Git repository URL:\n    - [GitLab Terraform GKE ArgoCD](https://gitlab.com/demos/infrastructure/gitlab-terraform-gke-argocd)\n6. Complete the fields and select **Create project**.\n\n\n#### Add in your cloud credentials to CI/CD variables\n\n\n1. To authenticate GCP with GitLab, create a GCP service account with the\nfollowing roles: **Compute Network Viewer, Kubernetes Engine Admin, Service\nAccount User, and Service Account Admin**. Both User and Admin service\naccounts are necessary. The User role impersonates the default service\naccount when creating the node pool. The Admin role creates a service\naccount in the kube-system namespace.\n\n2. **Download the JSON file** with the service account key you created in\nthe previous step.\n\n3. On your computer, encode the JSON file to base64 (replace\n/path/to/sa-key.json to the path to your key):\n\n\n```\n\nbase64 -i /path/to/sa-key.json\n\n```\n\n\n4. Use the output of this command as the **BASE64_GOOGLE_CREDENTIALS**\nenvironment variable in the next step.\n\n\nOn the left sidebar, select **Settings > CI/CD. Expand Variables**.\n\n5. Set the variable **BASE64_GOOGLE_CREDENTIALS** to the base64 encoded JSON\nfile you just created.\n\n6. Set the variable **TF_VAR_gcp_project** to your GCP’s project name.\n\n\n![simpleargocd - image\n1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683298/Blog/Content%20Images/simpleargocd_-_image_1.png)\n\n\n#### Run GitLab CI to deploy your Kubernetes cluster with ArgoCD Installed.\n\n\n![simpleargocd - image\n2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683298/Blog/Content%20Images/simpleargocd_-_image_2.png)\n\n\n#### Connect to your GKE Cluster through your terminal using the following\nbash command.\n\n\n```bash\n\ngcloud container clusters get-credentials gitlab-terraform-gke-argocd\n--region us-central1 --project \u003Cproject-name>\n\n```\n\n\n![simpleargocd-image3](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683298/Blog/Content%20Images/simpleargocd-image3.png)\n\n\n#### Expose the Initial Admin Secret through your terminal using the\nfollowing bash command. Make sure you save this password for later.\n\n\n```bash\n\nkubectl -n argocd get secret argocd-initial-admin-secret -o\njsonpath=\"{.data.password}\" | base64 -d\n\n```\n\n\n#### Port Forward ArgoCD to your localhost 8080 through your terminal using\nthe following bash command. Go to Chrome localhost:8080 afterwards.\n\n\n```bash\n\nkubectl port-forward svc/argocd-server -n argocd 8080:443\n\n```\n\n\n#### Enter your admin and `Initial Admin Secret` to the login page.\n\n\n![simpleargocd - image\n4](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683298/Blog/Content%20Images/simpleargocd_-_image_4.png)\n\n\n#### Voila! You've bootstrapped your GKE cluster with ArgoCD. Enjoy your\nGitOps!\n\n\n![simpleargocd - image\n5](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683298/Blog/Content%20Images/simpleargocd_-_image_5.png)\n\n\n### Next steps\n\nWe recommend reviewing [setting up Review Ops with\nArgoCD](https://about.gitlab.com/blog/how-to-provision-reviewops/)! \n\n\n### References\n\n- [GitLab Learn Labs - Infrastructure\nWebinar](https://gitlab.com/gitlab-learn-labs/webinars/infrastructure/gitlab-terraform-gke-argocd)\n\n- [Getting started with\nArgoCD](https://argo-cd.readthedocs.io/en/release-2.0/getting_started/)\n\n\n### Related posts\n\n- [Simple Kubernetes management with\nGitLab](https://about.gitlab.com/blog/simple-kubernetes-management-with-gitlab/)\n\n- [How to provision\nReviewOps](https://about.gitlab.com/blog/how-to-provision-reviewops/)\n\n- [The ultimate guide to GitOps with\nGitLab](https://about.gitlab.com/blog/the-ultimate-guide-to-gitops-with-gitlab/)\n",[550,3194,109,9,1259],"GKE",{"slug":3196,"featured":6,"template":698},"quick-setup-of-a-gke-cluster-with-argocd-pre-installed-using-terraform","content:en-us:blog:quick-setup-of-a-gke-cluster-with-argocd-pre-installed-using-terraform.yml","Quick Setup Of A Gke Cluster With Argocd Pre Installed Using Terraform","en-us/blog/quick-setup-of-a-gke-cluster-with-argocd-pre-installed-using-terraform.yml","en-us/blog/quick-setup-of-a-gke-cluster-with-argocd-pre-installed-using-terraform",{"_path":3202,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3203,"content":3206,"config":3212,"_id":3214,"_type":14,"title":3215,"_source":16,"_file":3216,"_stem":3217,"_extension":19},"/en-us/blog/reduce-the-load-on-gitlab-gitaly-with-bundle-uri",{"noIndex":6,"title":3204,"description":3205},"Reduce the load on GitLab Gitaly with bundle URI","Discover what the bundle URI Git feature is, how it is integrated into Gitaly, configuration best practices, and how GitLab users can benefit from it.",{"title":3204,"description":3205,"heroImage":3207,"date":1827,"body":3208,"category":848,"tags":3209,"authors":3210},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099013/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%2814%29_6VTUA8mUhOZNDaRVNPeKwl_1750099012960.png","Gitaly plays a vital role in the GitLab ecosystem — it is the server\ncomponent that handles all Git operations. Every push and pull made to/from\na repository is handled by Gitaly, which has direct access to the disk where\nthe actual repositories are stored. As a result, when Gitaly is under heavy\nload, some operations like CI/CD pipelines and browsing a repository in the\nGitLab UI can become quite slow. This is particularly true when serving\nclones and fetches for large and busy monorepos, which can consume large\namounts of CPU and memory.\n\n\n[Bundle URI](https://docs.gitlab.com/administration/gitaly/bundle_uris/) takes significant load off of Gitaly servers during clones by allowing Git to pre-download a bundled repository from object storage before calling the Gitaly servers to fetch the remaining objects.\n\n\nHere is a graph that shows the difference between clones without and with bundle URI.\n\n\n![Graph that shows the difference between clones without and with bundle URI](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750705069/rvbm4ru1w58msd6zv4x7.png)\n\n\nThis graph shows the results of a small test we ran on an isolated GitLab installation, with Gitaly running on a machine with 2 CPUs. We wanted to test bundle URI with a large repository, so we pushed the [GitLab repository](https://gitlab.com/gitlab-org/gitlab) to the instance. We also generated a bundle beforehand.\n\n\nThe big CPU spike is from when we performed a single clone of the GitLab repository with bundle URI disabled. It's quite noticeable. A little later, we turned on bundle URI and launched three concurrent clones of the GitLab repository. Sure enough, turning on bundle URI provides massive performance gain. We can't even distinguish the CPU usage of the three clones from normal usage.\n\n\n## Configure Gitaly to use bundle URI\n\n\nTo enable bundle URI on your GitLab installation, there are a couple of things you need to configure.\n\n\n### Create a cloud bucket\n\n\nBundles need to be stored somewhere. The ideal place is in a cloud storage bucket. Gitaly uses the [gocloud.dev](https://pkg.go.dev/gocloud.dev) library to read and write from cloud storage. Any cloud storage solution supported by this library can be used. Once you have a cloud bucket URL, you can add it in the Gitaly configuration here:\n\n\n```toml\n[bundle_uri]\ngo_cloud_url = \"\u003Cbucket-uri>\"\n```\n\n\nIt must be noted that Gitaly does not manage the lifecycle of the bundles stored in the bucket. To avoid cost issues, object lifecycle policies must be enabled on the bucket in order to delete unused or old objects.\n\n\n### Enable the feature flags\n\n\nThere are two feature flags to enable:\n\n\n- `gitaly_bundle_generation` enables [auto-generation](#auto-generated) of bundles.\n\n\n- `gitaly_bundle_uri` makes Gitaly advertise bundle URIs when they are available (either manually created or auto-generated) and allows the user to [manually](#manual) generate bundles.\n\n\nThese feature flags can be enabled at-large on a GitLab installation, or per repository. See the [documentation on how to enable a GitLab feature behind a feature flag](https://docs.gitlab.com/administration/feature_flags/#how-to-enable-and-disable-features-behind-flags).\n\n\n### How to generate bundles\n\n\nGitaly offers two ways for users to use bundle URI: a [manual](#manual) way and an [auto-generated](#auto-generated) way.\n\n\n#### Manual\n\n\nIt is possible to create a bundle manually by connecting over SSH with the Gitaly node that stores the repository you want to create a bundle for, and run the following command:\n\n```shell\nsudo -u git -- /opt/gitlab/embedded/bin/gitaly bundle-uri \n--config=\u003Cconfig-file>\n--storage=\u003Cstorage-name>\n--repository=\u003Crelative-path>\n```\n\nThis command will create a bundle for the given repository and store it into the bucket configured above. When a subsequent `git clone` request will reach Gitaly for the same repository, the bundle URI mechanism described above will come into play.\n\n\n#### Auto-generated\n\n\nGitaly can also generate bundles automatically, using a heuristic to determine if it is currently handling frequent clones for the same repository.\n\n\nThe current heuristic keeps track of the number of times a `git fetch` request is issued for each repository. If the number of requests reaches a certain `threshold` in a given time `interval`, a bundle is automatically generated. Gitaly also keeps track of the last time it generated a bundle for a repository. When a new bundle should be regenerated, based on the `threshold` and `interval`, Gitaly looks at the last time a bundle was generated for the given repository. It will only generate a new bundle if the existing bundle is older than some `maxBundleAge` configuration. The old bundle is overwritten. There can only be one bundle per repository in cloud storage.\n\n\n## Using bundle URI\n\n\nWhen a bundle exists for a repository, it can be used by the `git clone` command.\n\n\n### Cloning from your terminal\n\n\nTo clone a repository from your terminal, make sure your Git configuration enables bundle URI. The configuration can be set like so:\n\n\n```shell\ngit config --global transfer.bundleuri true\n```\n\nTo verify that bundle URI is used during a clone, you can run the `git clone` command with `GIT_TRACE=1` and see if your bundle is being downloaded:\n```shell\n➜  GIT_TRACE=1 git clone https://gitlab.com/gitlab-org/gitaly\n...\n14:31:42.374912 run-command.c:667       trace: run_command: git-remote-https '\u003Cbundle-uri>'\n...\n```\n\n### Cloning during CI/CD pipelines\n\n\nOne scenario where using bundle URI would be beneficial is during a CI/CD pipeline, where each job needs a copy of the repository in order to run. Cloning a repository during a CI/CD pipeline is the same as cloning a repository from your terminal, except that the Git client in this case is the GitLab Runner. Thus, we need to configure the GitLab Runner in such a way that it can use bundle URI.\n\n\n**1. Update the helper-image**\n\n\nThe first thing to do to configure the GitLab Runner is to [overwrite the helper-image](https://docs.gitlab.com/runner/configuration/advanced-configuration/#override-the-helper-image) that your GitLab Runner instances use. The `helper-image` is the image that is used to run the process of cloning a repository before the job starts. To use bundle URI, the image needs the following:\n\n\n- Git Version 2.49.0 or later\n\n\n- [`GitLab Runner helper`](https://gitlab.com/gitlab-org/gitlab-runner/-/tree/main/apps/gitlab-runner-helper?ref_type=heads) Version 18.1.0 or later\n\n\nThe helper-images can be found [here](https://gitlab.com/gitlab-org/gitlab-runner/container_registry/1472754?orderBy=PUBLISHED_AT&sort=desc&search[]=v18.1.0). Select an image that corresponds to the OS distribution and the architecture you use for your GitLab Runner instances, and verify that the image satisfies the requirements.\n\n\nAt the time of writing, the `alpine-edge-\u003Carch>-v18.1.0*` tag meets all requirements.\n\nYou can validate the image meets all requirements with:\n\n```shell\ndocker run -it \u003Cimage:tag>\n$ git version ## must be 2.49.0 or newer\n$ gitlab-runner-helper -v ## must be 18.0 or newer\n```\n\nIf you do not find an image that meets the requirements, you can also use the helper-image as a base image and install the requirements yourself in a custom-built image that you can host on [GitLab Container Registry](https://docs.gitlab.com/user/packages/container_registry/).\n\n\nOnce you have found the image you need, you must configure your GitLab Runner instances to use it by updating your `config.toml` file:\n\n\n```toml\n[[runners]]\n (...)\n executor = \"docker\"\n [runners.docker]\n    (...)\n    helper_image = \"image:tag\" ## \u003C-- put the image name and tag here\n```\n\n\nOnce the configuration is changed, you must restart the runners for the new configuration to take effect.\n\n\n**2. Turn on the feature flag**\n\n\nNext, you must enable the `FF_USE_GIT_NATIVE_CLONE` [GitLab Runner feature flags](https://docs.gitlab.com/runner/configuration/feature-flags/) in your `.gitlab-ci.yml` file. To do that, simply add it as a variable and set to `true` :\n\n```yaml\nvariables:\n  FF_USE_GIT_NATIVE_CLONE: \"true\"\n```\n\n\nThe `GIT_STRATEGY` must also be [set to `clone`](\u003Chttps://docs.gitlab.com/ci/runners/configure_runners/#git-strategy>), as Git bundle URI only works with `clone` commands.\n\n\n## How bundle URI works\n\n\nWhen a user clones a repository with the `git clone` command, a process called [`git-receive-pack`](https://git-scm.com/docs/git-receive-pack) is launched on the client's machine. This process communicates with the remote repository's server (it can be over HTTP/S, SSH, etc.) and asks to start a [`git-upload-pack`](https://git-scm.com/docs/git-receive-pack) process. Those two processes then exchange information using the Git protocol (it must be noted that bundle URI is only supported with [Git protocol v2](https://git-scm.com/docs/protocol-v2)). The capabilities both processes support and the references and objects the client needs are among the information exchanged. Once the Git server has determined which objects to send to the client, it must package them into a packfile, which, depending on the size of the data it must process, can consume a good amount of resources.\n\n\nWhere does bundle URI fit into this interaction? If bundle URI is advertised as a capability from the `upload-pack` process and the client supports bundle URI, the Git client will ask the server if it knows about any bundle URIs. The server sends those URIs back and the client downloads those bundles.\n\n\nHere is a diagram that shows those interactions:\n\n\n```mermaid\n\nsequenceDiagram\n\n\n    participant receive as Client\n\n\n    participant upload as Server\n\n\n    participant cloud as File server\n\n\n    receive ->> upload: issue git-upload-pack\n\n\n    upload -->> receive: list of server capabilities\n\n\n    opt if bundle URI is advertised as a capability\n\n\n    receive ->> upload: request bundle URI\n\n\n    upload -->> receive: bundle URI\n\n\n    receive ->> cloud: download bundle at URI\n\n\n    cloud -->> receive: bundle file\n\n\n    receive ->> receive: clone from bundle\n\n\n    end\n\n\n    receive ->> upload: requests missing references and objects\n\n\n    upload -->> receive: packfile data\n\n```\n\n\nAs such, Git [bundle URI](https://git-scm.com/docs/bundle-uri) is a mechanism by which, during a `git clone`, a Git server can advertise the URI of a bundle for the repository being cloned by the Git client. When that is the case, the Git client can clone the repository from the bundle and request from the Git server only the missing references or objects that were not part of the bundle. This mechanism really helps to alleviate pressure from the Git server.\n\n\n## Alternatives\n\n\nGitLab also has a feature [Pack-objects cache](https://docs.gitlab.com/administration/gitaly/configure_gitaly/#pack-objects-cache). This feature works slightly differently than bundle URI. When the server packs objects together into a so-called packfile, this feature will keep that file in the cache. When another client needs the same set of objects, it doesn't need to repack them, but it can just send the same packfile again.\n\n\nThe feature is only beneficial when many clients request the exact same set of objects. In a repository that is quick-changing, this feature might not give any improvements. With bundle URI, it doesn't matter if the bundle is slightly out-of-date because the client can request missing objects after downloading the bundle and apply those changes on top. Also bundle URI in Gitaly stores the bundles on external storage, which the Pack-objects Cache stores them on the Gitaly node, so using the latter doesn't reduce network and I/O load on the Gitaly server.\n\n\n## Try bundle URI today\n\n\nYou can try the bundle URI feature in one of the following ways:\n\n\n* Download a [free trial version of GitLab Ultimate](https://about.gitlab.com/free-trial/).\n\n\n* If you already run a self-hosted GitLab installation, upgrade to 18.1.\n\n\n* If you can't upgrade to 18.1 at this time, [download GitLab](https://about.gitlab.com/install/) to a local machine.",[848,9,1041],[3211],"Olivier Campeau",{"featured":6,"template":698,"slug":3213},"reduce-the-load-on-gitlab-gitaly-with-bundle-uri","content:en-us:blog:reduce-the-load-on-gitlab-gitaly-with-bundle-uri.yml","Reduce The Load On Gitlab Gitaly With Bundle Uri","en-us/blog/reduce-the-load-on-gitlab-gitaly-with-bundle-uri.yml","en-us/blog/reduce-the-load-on-gitlab-gitaly-with-bundle-uri",{"_path":3219,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3220,"content":3226,"config":3231,"_id":3233,"_type":14,"title":3234,"_source":16,"_file":3235,"_stem":3236,"_extension":19},"/en-us/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo",{"title":3221,"description":3222,"ogTitle":3221,"ogDescription":3222,"noIndex":6,"ogImage":3223,"ogUrl":3224,"ogSiteName":686,"ogType":687,"canonicalUrls":3224,"schema":3225},"Refactor code into modern languages with AI-powered GitLab Duo ","This detailed tutorial helps developers use AI to modernize code by switching to a new programming language and gain knowledge about new features in the same language.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662465/Blog/Hero%20Images/GitLab_Duo_Workflow_Unified_Data_Store__1_.png","https://about.gitlab.com/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Refactor code into modern languages with AI-powered GitLab Duo \",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Michael Friedrich\"}],\n        \"datePublished\": \"2024-08-26\",\n      }",{"title":3221,"description":3222,"authors":3227,"heroImage":3223,"date":3228,"body":3229,"category":781,"tags":3230},[1318],"2024-08-26","Whether you are tasked with modernizing the code base or framework by\nswitching to a new programming language, or you need knowledge about new\nlanguage features in the same language, AI-powered [GitLab\nDuo](https://about.gitlab.com/gitlab-duo/) can help. Learn how to approach\ncode refactoring challenges with best practices using examples from the past\n20 years of my coding career. \n\n\nThe prompts and examples in this article are shown in different IDEs: VS\nCode and JetBrains IDEs (IntelliJ IDEA, PyCharm, and CLion) with the [GitLab\nDuo\nextensions/plugins](https://docs.gitlab.com/ee/user/project/repository/code_suggestions/supported_extensions.html)\ninstalled. The development environment uses GitLab.com, including updates to\nAnthropic Claude 3.5 as Large Language Model (LLM) for GitLab Duo [Code\nSuggestions](https://docs.gitlab.com/ee/user/gitlab_duo/#code-suggestions)\nand [Chat](https://docs.gitlab.com/ee/user/gitlab_duo/#gitlab-duo-chat).\nSpoiler: They are even more powerful and efficient.\n\n\nYou can navigate into each section of the article, or read top-down. The\nsource code and challenges with exercises are provided for self-learning,\ntoo.\n\n\n- [Refactor code to modern programming language\nstandards](#refactor-code-to-modern-programming-language-standards)\n    - [Generate Java 7 and refactor to Java 8](#generate-java-7-and-refactor-to-java-8)\n    - [Refactor across C++ standards](#refactor-across-c%2B%2B-standards)\n        - [Migration: Refactor C++03 into C++14](#migration-refactor-c%2B%2B03-into-c%2B%2B14)\n        - [Downgrade: Refactor C++23 to C++11](#downgrade-refactor-c%2B%2B23-to-c%2B%2B11)\n    - [Explain and refactor COBOL](#explain-and-refactor-cobol)\n- [Refactor a language into another\nlanguage](#refactor-a-language-into-another-language)\n    - [Refactor C to Rust](#refactor-c-to-rust)\n    - [Refactor Perl to Python](#refactor-perl-to-python)\n- [More refactoring hands-on](#more-refactoring-hands-on)\n    - [Refactor JavaScript](#refactor-javascript)\n    - [Refactor Bash to ZSH or SH](#refactor-bash-to-zsh-or-sh)\n    - [More use cases and tutorials](#more-use-cases-and-tutorials)\n- [Key takeaways](#key-takeaways)\n\n\n## Refactor code to modern programming language standards\n\n\nThe next sections show how to refactor, explain, and understand the language\nspecific differences in a defined programming language. \n\n\n### Generate Java 7 and refactor to Java 8 \n\n\nA customer wanted to know if GitLab Duo supports Java 7. While testing the\nCode Suggestions and Chat prompts to generate Java 7 specific code, I also\nthought of migration help. Anthropic Claude 3.5 is capable of understanding\nthe language-specific differences, and so is GitLab Duo.\n\n\nThe following example shows a prompt to generate Java 7 code with Code\nSuggestions.\n\n\n```java\n\n// Generate a new class for a File Manager. Use Java 7 features only.\n\nimport java.io.*;\n\nimport java.nio.file.*;\n\nimport java.util.*;\n\n\npublic class FileManager {\n    private Path rootDirectory;\n\n    public FileManager(String rootPath) throws IOException {\n        this.rootDirectory = Paths.get(rootPath);\n        if (!Files.exists(rootDirectory)) {\n            Files.createDirectories(rootDirectory);\n        }\n    }\n\n    public void createFile(String fileName, String content) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        Files.write(filePath, content.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);\n    }\n\n    public String readFile(String fileName) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        return new String(Files.readAllBytes(filePath));\n    }\n\n    public void deleteFile(String fileName) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        Files.delete(filePath);\n    }\n\n    public List\u003CString> listFiles() throws IOException {\n        List\u003CString> fileList = new ArrayList\u003C>();\n        try (DirectoryStream\u003CPath> stream = Files.newDirectoryStream(rootDirectory)) {\n            for (Path file : stream) {\n                fileList.add(file.getFileName().toString());\n            }\n        }\n        return fileList;\n    }\n\n    public void copyFile(String sourceFileName, String destinationFileName) throws IOException {\n        Path sourcePath = rootDirectory.resolve(sourceFileName);\n        Path destinationPath = rootDirectory.resolve(destinationFileName);\n        Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);\n    }\n\n    public void moveFile(String sourceFileName, String destinationFileName) throws IOException {\n        Path sourcePath = rootDirectory.resolve(sourceFileName);\n        Path destinationPath = rootDirectory.resolve(destinationFileName);\n        Files.move(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);\n    }\n\n    public long getFileSize(String fileName) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        return Files.size(filePath);\n    }\n\n    public boolean fileExists(String fileName) {\n        Path filePath = rootDirectory.resolve(fileName);\n        return Files.exists(filePath);\n    }\n}\n\n```\n\n\nYou can continue with the following steps in your IDE:\n\n\n1. Learn and understand the generated code: Select the code in the editor\n(blue color in the screenshot), switch into GitLab Duo Chat and send the\n`/explain` slash command as prompt.\n\n\n![Validate the generated code with the `/explain` slash command in GitLab\nDuo\nChat](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/intellij_java7_generate_refactor.png)\n\n\n2. Refactor the Java 7 code into Java 8: Select the code in the editor,\nswitch into Chat, and send `/refactor using Java 8 features` as refined\nprompt.\n\n3. Practice an alternative to refactoring: Create a new file `java8.java`\nand generate Java 8 specific code using Code Suggestions with the prompt `//\nGenerate a new class for a File Manager. Use Java 8 features only.`.\n\n4. Continue writing Java 8 code in the same context with AI-powered code\ncompletions.\n\n\nYou can watch all steps in this recording.\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/XKRv6uBkD2I\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\nThe source code is available in the [GitLab Duo Challenge - Generate and\nrefactor Java 7 to 8\nproject](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-generate-refactor-java-7-to-8).\n\n\n### Refactor across C++ standards\n\n\nThe C++ standard has a long history and can be considered stable and mature.\nDepending on the target architecture and platforms, the supported standard\ndepends on the compiler on the host operating system.\n\n\nIn my career, I needed to support 25 different Linux and Windows\ndistributions in open source projects, and have seen varying compiler\nsupport for newer language features and C++ standards. In 2015, we settled\non C++11 features, and later never touched based on C++14 or C++17. \n\n\nRefactoring functions and algorithms to a new C++ standard would have\nrequired too much effort, and help explaining the differences was needed.\nBack then, we researched through books, online search, Stack Overflow, and\nsometimes tools assistance for refactoring.\n\n\nThings have changed with AI-powered assistants and GitLab Duo: You can\ninstruct Code Suggestions and Chat to provide source code in a specific C++\nstandard. Then, it is also possible to compare the different outputs. \n\n\nThe following example uses a prompt to specifically generate source code for\nthe C++03 standard. It implements a simple config parser for the `.ini`\nconfiguration format.\n\n\n```c++\n\n/* Create a config parser which can parse an ini format\n\nUse C++03 standard only\n */\n\n#include \u003Ciostream>\n\n#include \u003Cfstream>\n\n#include \u003Cstring>\n\n#include \u003Cmap>\n\n#include \u003Csstream>\n\n\nclass ConfigParser {\n\nprivate:\n    std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> > config;\n\npublic:\n    ConfigParser() {}\n\n    bool parse(const std::string& filename) {\n        std::ifstream file(filename.c_str());\n        if (!file.is_open()) {\n            return false;\n        }\n\n        std::string line;\n        std::string currentSection;\n\n        while (std::getline(file, line)) {\n            // Trim whitespace\n            size_t first = line.find_first_not_of(\" \\t\");\n            size_t last = line.find_last_not_of(\" \\t\");\n            if (first == std::string::npos) continue; // Skip empty lines\n            line = line.substr(first, (last - first + 1));\n\n            if (line[0] == '[' && line[line.length() - 1] == ']') {\n                // This is a section\n                currentSection = line.substr(1, line.length() - 2);\n            } else {\n                // This is a key-value pair\n                size_t delimiterPos = line.find('=');\n                if (delimiterPos != std::string::npos) {\n                    std::string key = line.substr(0, delimiterPos);\n                    std::string value = line.substr(delimiterPos + 1);\n                    config[currentSection][key] = value;\n                }\n            }\n        }\n\n        file.close();\n        return true;\n    }\n\n    std::string getValue(const std::string& section, const std::string& key) const {\n        std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> >::const_iterator sectionIt = config.find(section);\n        if (sectionIt != config.end()) {\n            std::map\u003Cstd::string, std::string>::const_iterator keyIt = sectionIt->second.find(key);\n            if (keyIt != sectionIt->second.end()) {\n                return keyIt->second;\n            }\n        }\n        return \"\";\n    }\n\n    void printConfig() const {\n        std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> >::const_iterator sectionIt;\n        for (sectionIt = config.begin(); sectionIt != config.end(); ++sectionIt) {\n            std::cout \u003C\u003C \"[\" \u003C\u003C sectionIt->first \u003C\u003C \"]\" \u003C\u003C std::endl;\n            std::map\u003Cstd::string, std::string>::const_iterator keyIt;\n            for (keyIt = sectionIt->second.begin(); keyIt != sectionIt->second.end(); ++keyIt) {\n                std::cout \u003C\u003C keyIt->first \u003C\u003C \" = \" \u003C\u003C keyIt->second \u003C\u003C std::endl;\n            }\n            std::cout \u003C\u003C std::endl;\n        }\n    }\n};\n\n\nint main() {\n    ConfigParser parser;\n    if (parser.parse(\"config.ini\")) {\n        std::cout \u003C\u003C \"Config file parsed successfully.\" \u003C\u003C std::endl;\n        parser.printConfig();\n\n        std::cout \u003C\u003C \"Value of 'key1' in 'section1': \" \u003C\u003C parser.getValue(\"section1\", \"key1\") \u003C\u003C std::endl;\n    } else {\n        std::cout \u003C\u003C \"Failed to parse config file.\" \u003C\u003C std::endl;\n    }\n    return 0;\n}\n\n```\n\n\nThe same prompts can be applied to [explaining\ncode](https://docs.gitlab.com/ee/user/gitlab_duo_chat/examples.html#explain-code-in-the-ide),\n[generating\ntests](https://docs.gitlab.com/ee/user/gitlab_duo_chat/examples.html#write-tests-in-the-ide),\nand even [refactoring\ncode](https://docs.gitlab.com/ee/user/gitlab_duo_chat/examples.html#refactor-code-in-the-ide):\n`/explain focus on C++03 features`, `/tests for C++03 features`, `/refactor\ninto C++03`. \n\n\nThe following C++ standards have been tested working with GitLab Duo Code\nSuggestions:\n\n\n- C++03\n\n- C++11\n\n- C++14\n\n- C++17\n\n- C++20\n\n- C++23\n\n\nYou can find the source code in the [Challenge - Refactor Cpp Standards\nConfig Parser\nproject](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-cpp-standards-config-parser). \n\n\nThere are many different combinations to refactor source code between the\nC++ standards. The following examples reflect on modernizing the C++ code\nwith version upgrades, but also test a downgrade where ambitious developers\nwanted to use C++20 but had to use C++11 to support enterprise customer\nenvironments.\n\n\n#### Migration: Refactor C++03 into C++14 \n\n\nThe goal is to modernize the code, and understand the changes between C++03\nand C++14. Open the\n[03.cpp](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-cpp-standards-config-parser/-/blob/main/03.cpp?ref_type=heads)\nsource code in the IDE, select it, and use the following Chat prompt: \n\n\n```markdown\n\n/refactor into C++14 and explain the changes\n\n```\n\n\nPotential Chat response: \n\n\n```markdown\n\n…\n\n\nExplanations of the changes:\n\n\n1. Default constructor: Changed `ConfigParser() {}` to `ConfigParser() =\ndefault;` to use the default constructor.\n\n2. File opening: Removed `.c_str()` when opening the file, as C++11 and\nlater support `std::string` directly.\n\n3. Lambda functions: Introduced a lambda function trim to handle string\ntrimming, making the code more readable and reusable.\n\n4. Auto keyword: Used `auto` for type deduction in various places, improving\ncode readability.\n\n5. Range-based for loops: In the `printConfig` method, replaced traditional\nfor loops with range-based for loops, which are more concise and less\nerror-prone.\n\n6. Structured bindings: Used structured bindings in the range-based for\nloops to directly access key-value pairs.\n\n7. If statements with initializers: In the `getValue` method, used if\nstatements with initializers to combine the find operation and the check in\na single line.\n\n8. String member functions: Used `front()` and `back()` instead of\narray-style access for the first and last characters of strings.\n\n9. Uniform initialization: Used uniform initialization `{}` instead of\nparentheses `()` for object creation.\n\n10. Removed `std::endl`: Replaced `std::endl` with `'\\n'` for better\nperformance, as `std::endl` forces a flush of the output buffer.\n\n\nThese changes make the code more modern, concise, and potentially more\nefficient while maintaining the same functionality.\n\n\n```\n\n\n![Changes reflected in\ncode](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp03_to_14_01.png)\n\n\n![Changes reflected in code\n2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675060/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp03_to_14_02.png)\n\n\n#### Downgrade: Refactor C++23 to C++11\n\n\nSometimes, developers started a new feature proof-of-concept in a modern C++\nstandard like C++20. The actual supported versions for enterprise customer\nenvironments require older compilers with C++11 support. Downgrading the\nversions come at a cost, and require evaluating which language features are\nstill supported, and which other disadvantages could come across.\n\n\nOpen the\n[23.cpp](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-cpp-standards-config-parser/-/blob/main/23.cpp?ref_type=heads)\nsource code in the IDE, select it, and use the following Chat prompt: \n\n\n```markdown\n\n/refactor into C++11, explain the necessary changes and potential problems\n\n```\n\n\nPotential Duo Chat response: \n\n\n```markdown\n\nThe main changes required to make this code compatible with C++11 are:\n\n\n1. Remove the C++23 standard comment, as it's no longer applicable.\n\n2. Replace `std::string::find_first_not_of` and\n`std::string::find_last_not_of` with C++11 compatible alternatives in the\ntrim function.\n\n3. Use `const auto&` instead of `auto` for loop variables to avoid\nunnecessary copying.\n\n\nPotential problems in the original code:\n\n\n1. The original code used C++23 features, which might not be widely\nsupported yet.\n\n2. The `trim` function used `std::string::find_first_not_of` and\n`std::string::find_last_not_of`, which are not available in C++11.\n\n3. The use of `auto` instead of `const auto&` in some loops could lead to\nunnecessary copying of complex objects.\n\n\nThese issues have been addressed in the refactored version. The `trim`\nfunction now uses `std::find_if_not` with lambda functions to achieve the\nsame result in a C++11 compatible way. The use of `const auto&` ensures that\nno unnecessary copying occurs when iterating over the config map.\n\n```\n\n\n![The `trim` function now uses `std::find_if_not` with lambda functions to\nachieve the same result in a C++11 compatible\nway](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp23_to_11_01.png)\n\n\n![The use of `const auto&` ensures that no unnecessary copying occurs when\niterating over the config\nmap](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp23_to_11_02.png)\n\n\n**Async practice**: Test more version refactoring scenarios.\n\n\n### Explain and refactor COBOL\n\n\nYou can use GitLab Duo to explain the source code, analyze, fix and refactor\nfor COBOL programs. I have never written nor learned COBOL, and found this\nhelpful [COBOL Programming\nCourse](https://github.com/openmainframeproject/cobol-programming-course)\nwith many examples.\n\n\nI then asked Chat how to get started with COBOL, create a COBOL program, and\ncompile a COBOL program on macOS.\n\n\n```markdown\n\nPlease explain what COBOL is and its syntax\n\n\nPlease create a COBOL program that shows the first steps\n\n\nTell me more about the COBOL compiler. Which system do I need? Can I do it\non my macOS?\n\n\n```\n\n\n![Asking GitLab Duo Chat to explain and its\nsyntax](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/vscode_chat_cobol_generate_example.png)\n\n\nOpen a COBOL program, select the source code, switch to Duo Chat and send\nthe `/explain` prompt to explain purpose and functionality.\n\n\nYou can also refine the prompts to get more high-level summaries, for\nexample:\n\n\n```markdown \n\n/explain like I am five\n\n```\n\n\n> Tip: Programming languages share similar algorithms and functionality. For\nCOBOL, Chat offered to explain it using Python, and, therefore, I adjusted\nfuture prompts to ask for an explanation in Python.\n\n\n```markdown\n\n/explain in a different programming language\n\n```\n\n\nYou can also use the `/refactor` slash command prompt in Chat to improve the\ncode quality, fix potential problems, and try to refactor COBOL into Python.\n\n\n```markdown\n\n/refactor fix the environment error\n\n\n/refactor fix potential problems\n\n\n/refactor into Python\n\n```\n\n\nThe [GitLab Duo Coffee Chat - Challenge: Explain and Refactor COBOL\nprograms](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-explain-refactor-cobol-program)\nrecording shows all discussed steps in a practical use case, including how\nto find a missing period: \n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/pwlDmLQMMPo\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n## Refactor a language into another language\n\n\nModernization and code quality improvements sometimes require the change of\na programming language. Similar refactor prompts with GitLab Duo can help\nspeed up the migration process. The COBOL example with Python is just one of\nmany requirements in enterprise environments -- let's dive into more use\ncases.\n\n\n### Refactor C to Rust \n\n\nIn early 2024, several programming languages, like C, have been called out\nfor not being memory safe. The recommendations for future projects include\n[memory safe\nlanguages](https://about.gitlab.com/blog/memory-safe-vs-unsafe/)\nlike Rust. But how do you start a migration, and what are the challenges?\n\n\nLet's try it with a simple example in C. The code was generated using Code\nSuggestions and should print the basic operating system information, like\nthe name, version, and platform. The C code compiles cross-platform on\nWindows, Linux, and macOS.\n\n\n```c\n\n// Read OS files to identify the platform, name, versions\n\n// Print them on the terminal\n\n#include \u003Cstdio.h>\n\n#include \u003Cstdlib.h>\n\n#include \u003Cstring.h>\n\n\n#ifdef _WIN32\n    #include \u003Cwindows.h>\n#elif __APPLE__\n    #include \u003Csys/utsname.h>\n#else\n    #include \u003Csys/utsname.h>\n#endif\n\n\nvoid get_os_info() {\n    #ifdef _WIN32\n        OSVERSIONINFOEX info;\n        ZeroMemory(&info, sizeof(OSVERSIONINFOEX));\n        info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);\n        GetVersionEx((OSVERSIONINFO*)&info);\n\n        printf(\"Platform: Windows\\n\");\n        printf(\"Version: %d.%d\\n\", info.dwMajorVersion, info.dwMinorVersion);\n        printf(\"Build: %d\\n\", info.dwBuildNumber);\n    #elif __APPLE__\n        struct utsname sys_info;\n        uname(&sys_info);\n\n        printf(\"Platform: macOS\\n\");\n        printf(\"Name: %s\\n\", sys_info.sysname);\n        printf(\"Version: %s\\n\", sys_info.release);\n    #else\n        struct utsname sys_info;\n        uname(&sys_info);\n\n        printf(\"Platform: %s\\n\", sys_info.sysname);\n        printf(\"Name: %s\\n\", sys_info.nodename);\n        printf(\"Version: %s\\n\", sys_info.release);\n    #endif\n}\n\n\nint main() {\n    get_os_info();\n    return 0;\n}\n\n```\n\n\nOpen the source code in\n[`os.c`](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-c-to-rust/-/blob/897bf57a14bb7be07d842e7f044f93a61456d611/c/os.c)\nin JetBrains CLion, for example. Select the source code and use the Chat\nprompt `/explain` to explain purpose and functionality. Next, use\n`/refactor` in the Chat prompt to refactor the C code, and then take it one\nstep further: `/refactor into Rust`. \n\n\nInitialize a new Rust project (Tip: Ask Duo Chat), and copy the generated\nsource code into the `src/main.rs` file. Run `cargo build` to compile the\ncode. \n\n\n![Initialize a new Rust project, and copy the generated source code into the\n`src/main.rs` file. Run `cargo build` to compile the\ncode.](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/jetbrains_clion_c_rust.png)\n\n\nIn the [GitLab Duo Coffee Chat: Challenge - Refactor C into\nRust](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-c-to-rust)\nrecording, you can learn all steps, and additionally, you'll see a\ncompilation error which gets fixed with the help of Chat and `/refactor`\nslash command. The session also shows how to improve the maintanability of\nthe new Rust code by adding more error handling. \n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/nf8g2ucqvkI\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n### Refactor Perl to Python \n\n\nThat one script that runs on production servers, does its job, the author\nleft the company ten years ago, and nobody wants to touch it. The problem\nmight also apply to multiple scripts, or even a whole application. A\ndecision was made to migrate everything to modern Python 3, with the goal to\nmodernize the code, and understand the changes between Perl and Python.\n\n\nA customer recently asked in a GitLab Duo workshop whether a direct\nmigration is possible using GitLab Duo. Short answer: Yes, it is. Longer\nanswer: You can use refined Chat prompts to refactor Perl code into Python,\nsimilar to other examples in this article.\n\n\nOpen the `script.pl` source code in IDE, select it, and open Chat.\n\n\n```perl\n\n#!/usr/bin/perl\n\nuse strict;\n\nuse warnings;\n\n\nopen my $md_fh, '\u003C', 'file.md' or die \"Could not open file.md: $!\";\n\n\nmy $l = 0;\n\nmy $e = 0;\n\nmy $h = 0;\n\n\nwhile (my $line = \u003C$md_fh>) {\n  $l++;\n  if ($line =~ /^\\s*$/) {\n    $e++;\n    next;\n  }\n  if ($line =~ /^#+\\s*(.+)/) {\n    print \"$1\\n\";\n    $h++; \n  }\n}\n\n\nprint \"\\nS:\\n\"; \n\nprint \"L: $l\\n\";\n\nprint \"E: $e\\n\"; \n\nprint \"H: $h\\n\";\n\n```\n\n\nYou can use the following prompts to:\n\n\n1. `/explain` its purpose, and `/refactor` to improve the code.\n\n2. `/refactor into Python` to get a working Python script.\n\n\n![Refactor into\nPython](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/pycharm_duo_refactor_perl_python.png)\n\n\n> Tip: You can refactor Perl code into more target languages. The [GitLab\nDuo Coffee Chat: Challenge - Refactor Perl to\nPython](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-perl-python)\nrecording shows PHP, Ruby, Rust, Go, Java, VB.NET, C#, and more.\n\n> \n\n> If you want to continue using Perl scripts, you can configure [Perl as\nadditional\nlanguage](https://docs.gitlab.com/ee/user/project/repository/code_suggestions/supported_extensions.html#add-support-for-more-languages)\nin Duo Code Suggestions. Chat already understands Perl and can help with\nquestions and slash command prompts, as you can see in the following\nrecording.\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/03HGhxXg9lw\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n## More Refactoring Hands-on \n\n\n### Refactor JavaScript \n\n\nEddie Jaoude shows how to refactor JavaScript to improve code quality or add\nfunctionality in a practical example. \n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/mHn8KOzpPNY\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n### Refactor Bash to ZSH or SH\n\n\nI have used Bash as a shell for 20 years and most recently switched to ZSH\non macOS. This resulted in script not working, or unknown errors in my\nterminal. Another use case for refactoring are shell limitations – some\noperating systems or Linux/Unix distributions do not provide Bash, only SH,\nfor example, Alpine.\n\n\n![Refactor shell\nscripts](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/intellj_refactor_shell_scripts.png)\n\n\nThe [GitLab Duo Coffee Chat: Challenge - Refactor Shell\nScripts](https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-shell-scripts)\nshows an example with a C program that can tail syslog files, and a build\nscript written in Bash. Throughout the challenge, Chat is queried with\n`/explain` and `/refactor` prompts to improve the code. It is also possible\nto refactor Bash into POSIX-compliant SH or ZSH. The session concludes with\nasking Chat to provide five different Shell script implementations, and\nexplain the key summaries. \n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/mssqYjlKGzU\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n### More use cases and tutorials\n\n\n- [Documentation: GitLab Duo use\ncases](https://docs.gitlab.com/ee/user/gitlab_duo/use_cases.html)\n\n- [Tutorial: Top tips for efficient AI-powered code suggestions with GitLab\nDuo](https://about.gitlab.com/blog/top-tips-for-efficient-ai-powered-code-suggestions-with-gitlab-duo/)\n\n- [Tutorial: 10 best practices for using AI-powered GitLab Duo\nChat](https://about.gitlab.com/blog/10-best-practices-for-using-ai-powered-gitlab-duo-chat/)\n\n\n## Key takeaways \n\n\n1. GitLab Duo provides efficient help with explaining and refactoring code. \n\n1. You can refactor code between language standards, and ask follow-up\nquestions in Chat.\n\n1. Code Suggestions prompts can generate specific language standards, and\ncode completion respects the current code context. \n\n1. Refactoring code into new programming languages helps with longer term\nmigration and modernization plans.\n\n1. Code can be \"downgraded\" into older system's supported language\nstandards.\n\n1. GitLab Duo can explain complex code and programming languages with\ndifferent programming language examples.\n\n1. The update to Anthropic Claude 3.5 on GitLab.com has improved the quality\nand speed of Code Suggestions and Chat once again (self-managed upgrade to\n17.3 recommended).\n\n1. There are no boundaries except your imagination, and production pain\npoints.\n\n\nLearn more about efficient Code Suggestions and Chat workflows, and start\nyour AI-powered code refactoring journey with GitLab Duo today!\n\n\n> [Start your free trial of GitLab\nDuo!](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/?type=free-trial&toggle=gitlab-duo-pro_)\n",[717,827,9],{"slug":3232,"featured":6,"template":698},"refactor-code-into-modern-languages-with-ai-powered-gitlab-duo","content:en-us:blog:refactor-code-into-modern-languages-with-ai-powered-gitlab-duo.yml","Refactor Code Into Modern Languages With Ai Powered Gitlab Duo","en-us/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo.yml","en-us/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo",{"_path":3238,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3239,"content":3244,"config":3249,"_id":3251,"_type":14,"title":3252,"_source":16,"_file":3253,"_stem":3254,"_extension":19},"/en-us/blog/refactoring-a-ci-cd-template-to-a-ci-cd-component",{"title":3240,"description":3241,"ogTitle":3240,"ogDescription":3241,"noIndex":6,"ogImage":3186,"ogUrl":3242,"ogSiteName":686,"ogType":687,"canonicalUrls":3242,"schema":3243},"Refactoring a CI/CD template to a CI/CD component","CI/CD components are the next generation of CI/CD templates, enhancing pipeline creation and maintenance. Learn how to transition from templates to components.","https://about.gitlab.com/blog/refactoring-a-ci-cd-template-to-a-ci-cd-component","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Refactoring a CI/CD template to a CI/CD component\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"}],\n        \"datePublished\": \"2024-03-04\",\n      }",{"title":3240,"description":3241,"authors":3245,"heroImage":3186,"date":3246,"body":3247,"category":909,"tags":3248},[1612],"2024-03-04","GitLab recently introduced [CI/CD components](https://docs.gitlab.com/ee/ci/components/) as the next generation of the traditional CI/CD templates, and a novel approach to constructing CI/CD pipelines. CI/CD components offer reusable pipeline configurations that can be customized using input parameters.\n\nAlthough GitLab continues to support templates, they come with certain drawbacks that are addressed by the introduction of components. Therefore, we highly recommend refactoring existing templates into CI/CD components.\n\nThis article will guide you through the steps of converting your current GitLab CI/CD templates into reusable CI/CD components. Prior familiarity with how to create CI/CD components is a prerequisite, which you can learn about in this blog post: [Introducing the GitLab CI/CD Catalog Beta](https://about.gitlab.com/blog/introducing-the-gitlab-ci-cd-catalog-beta/).\n\n## How to convert a template to a component\n\nThese are the steps to convert a CI/CD template to a CI/CD component:\n1. Create a component project if you don’t have one. \n2. Copy your existing templates to the ‘templates’ directory in the component project. \n3. For each template, review the jobs listed in it and assess whether you prefer to distribute them across different components or retain some or all within the same component. While it's possible to include multiple jobs in a single component, it's advisable to create components that perform minimal tasks. This approach enhances ease of reuse and flexibility.\n4. Create a new section at the top of the configuration for the input parameters and meta data using the `spec` keyword. \n5. Replace any custom CI/CD variables and any other hard-coded values with [inputs](https://about.gitlab.com/blog/use-inputs-in-includable-files/) to maximize flexibility for consumption. Consider parameterizing elements such as stage, image, job name/job prefix, etc. \n6. Follow the [best practices](https://docs.gitlab.com/ee/ci/components/index.html#best-practices) for components.\n7. Improve the configuration, for example by enabling [merge request pipelines](https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html) or making it [more efficient](https://docs.gitlab.com/ee/ci/pipelines/pipeline_efficiency.html).\n\nHere is a code example of a job in an existing template:\n\n![existing template](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749678076/Blog/Content%20Images/Screenshot_2024-03-03_at_12.05.25.png)\n\nAnd this is the refactored [component code](https://gitlab.com/components/aws/-/blob/main/templates/ec2-deploy-production.yml?ref_type=heads):\n\n![Converted component](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749678077/Blog/Content%20Images/Screenshot_2024-03-03_at_12.07.14.png)\n\nOnce your components are ready, you can publish them to the CI/CD catalog so others will be able to find and consume them. \n\n## Take a product tour\n\nWe've prepared a brief product tour so you can quickly dive into the CI/CD catalog and see it in action (use the \"Next\" button to progress through the demo).\n\n[![Product tour of CI/CD catalog](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749678076/Blog/Content%20Images/Screenshot_2024-03-03_at_12.18.09.png)](https://gitlab.navattic.com/cicd-catalog)\n\n## Additional resources \n\nPlease refer to the official documentation on CI/CD components for more on how to [convert templates to components](https://docs.gitlab.com/ee/ci/components/#convert-a-cicd-template-to-a-component).\n\nYou can explore [an additional practical example](https://docs.gitlab.com/ee/ci/components/examples.html#cicd-component-migration-examples), demonstrating the steps to convert GitLab Go templates to CI/CD components.\n\nThen, you can watch the following video where [Fabio Pitino](https://about.gitlab.com/company/team/#fabiopitino), GitLab Principal Engineer, demonstrates the process of refactoring GitLab AWS templates to CI/CD components.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/dGCPrIAuBmE?si=1vjG_aEziY5jn-YC\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line –->\n",[109,9,827],{"slug":3250,"featured":91,"template":698},"refactoring-a-ci-cd-template-to-a-ci-cd-component","content:en-us:blog:refactoring-a-ci-cd-template-to-a-ci-cd-component.yml","Refactoring A Ci Cd Template To A Ci Cd Component","en-us/blog/refactoring-a-ci-cd-template-to-a-ci-cd-component.yml","en-us/blog/refactoring-a-ci-cd-template-to-a-ci-cd-component",{"_path":3256,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3257,"content":3263,"config":3269,"_id":3271,"_type":14,"title":3272,"_source":16,"_file":3273,"_stem":3274,"_extension":19},"/en-us/blog/remote-development-beta",{"title":3258,"description":3259,"ogTitle":3258,"ogDescription":3259,"noIndex":6,"ogImage":3260,"ogUrl":3261,"ogSiteName":686,"ogType":687,"canonicalUrls":3261,"schema":3262},"Behind the scenes of the Remote Development Beta release","Discover the epic journey of GitLab's Remote Development team as they navigate last-minute pivots, adapt, and deliver new features for users worldwide.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679888/Blog/Hero%20Images/remotedevelopment.jpg","https://about.gitlab.com/blog/remote-development-beta","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Behind the scenes of the Remote Development Beta release\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"David O'Regan\"}],\n        \"datePublished\": \"2023-08-16\",\n      }",{"title":3258,"description":3259,"authors":3264,"heroImage":3260,"date":3265,"body":3266,"category":909,"tags":3267},[1886],"2023-08-16","\nIn May 2023, the Create:IDE team faced an epic challenge – to merge the [Remote Development Rails monolith integration branch](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/105783) into the `master` branch of the GitLab Project. This was no small ask, as the merge request was of considerable size and complexity. In this blog post, we'll delve into the background, justifications, and process behind this endeavor.\n\nThe merge request titled \"Remote Development feature behind a feature flag\" was initiated by the Create:IDE team, aiming to merge the branch \"remote_dev\" into the \"master\" branch in the Rails monolith GitLab project. The MR contained `4` commits, `258` pipelines, and `143` changes that amounted to a total of `+7243` lines of code added to the codebase.\n\nInitially, the MR was created to reflect the work related to \"Remote Development\" under the \"Category: Remote Development.\" It was primarily intended to have CI pipeline coverage for the integration branch and was not meant for individual review or direct merging. The plan was to merge this code into the master branch via the [\"Remote Development Beta - Review and merge\" Epic](https://gitlab.com/groups/gitlab-org/-/epics/10258).\n\n![SUM](https://about.gitlab.com/images/blogimages/remote-development/SUM.png){: .shadow.medium}\n\n### How the Remote Development project started\nAs a team, we embarked on an ambitious journey to create a greenfield feature: the [Remote Development](https://docs.gitlab.com/ee/user/project/remote_development/) offering at GitLab. This feature had a vast scope, many unknowns, and required solving numerous new problems. To efficiently tackle this task, we decided to work on an integration branch using a [low-ceremony process](https://stackoverflow.com/questions/68092498/what-does-low-ceremony-mean). This decision enabled us to develop and release the feature in an impressively short time frame of less than four months.\n\nWorking on an integration branch provided us the flexibility to make significant progress, but it was always intended to eventually break down the work into smaller, iterative MRs that would follow the standard [GitLab review process](https://docs.gitlab.com/ee/development/code_review.html). We had a [detailed plan](https://gitlab.com/gitlab-org/remote-development/gitlab-remote-development-docs/-/blob/main/doc/integration-branch-process.md#master-mr-process-summary) for this process, but we realized that following the original plan would not allow us to meet our goal of releasing of the feature in GitLab 16.0.\n\n### Merging the integration branch MR without breaking it up\nDuring the development of the Remote Development feature, our team faced several challenges that led us to adopt a new approach for merging the integration branch into the master. First, as part of our [velocity-based XP/Scrum style process](https://about.gitlab.com/handbook/engineering/development/dev/create/ide/#-remote-development-iteration-planning), we realized that meeting the 16.0 release goal would require us to cut scope. A velocity report, \"[Velocity-based agile planning report](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/118436),\" highlighted that breaking down and reviewing individual MRs would take too long, considering the impending due date and the likelihood of last-minute scope additions.\n\nSecond, we [made the decision](https://gitlab.com/gitlab-org/gitlab/-/issues/398227#note_1361192858) to release workspaces as a **beta feature for public projects** for customers in [GitLab 16.0](/releases/2023/05/22/gitlab-16-0-released/#remote-development-workspaces-available-in-beta-for-public-projects). This approach reduced the complexity of the rollout plan and allowed us to get valuable feedback earlier, but required us to enable the feature by default earlier than planned. To align with this decision, we determined that merging the integration branch after review was the best course of action. An announcement was made to explain the change in plan, and we set specific timelines for the review process to ensure smooth coordination.\n\n> Hello Reviewers/Maintainers 👋 We have opened up a Zoom room through all of next week as an easy sync place for us all to collaborate and triage questions. As the MR is quite large, it might be overwhelming to determine where to begin. To help, we will aim to furnish a summary of what we have included, such as two new database tables and a couple of GraphQL/REST APIs. We will also be available through the week in the Zoom room and without it being too prescriptive of a approach, I would suggest we do a sync walkthrough of the MR first and then kick off the reviews.\n\nAddressing the concerns about risk, team members discussed the challenges and potential solutions. While there were apprehensions, we were confident in the overall quality of the feature. A disciplined plan for merging MRs was initially considered, but based on our velocity metrics, it was evident that meeting the public beta release goal required a new strategy.\n\nDespite the deviations from our usual practices, we acknowledged the urgency to deliver the initial release on time. The decision was not taken lightly, and we ensured that the merge had extensive [test coverage](https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html) and [feature flags](https://docs.gitlab.com/ee/operations/feature_flags.html) in place to address any potential issues. We accepted that some aspects would be overlooked in the initial MR review cycle, but we committed to addressing them in subsequent iterations.\n\n### Keeping the pipeline green and stable for the merge\nTo ensure the successful merge of the integration branch containing the Remote Development feature, our team made significant efforts to keep the pipeline green and stable. As the MR was quite large and contained critical functionality, it was crucial to maintain a high level of quality and reduce the risk of introducing regressions.\n\nTo address these challenges, the team adopted a disciplined approach to [CI/CD](https://about.gitlab.com/topics/ci-cd/). Throughout the development process, CI pipelines were carefully monitored, and any failing tests or issues were promptly addressed. The team conducted rigorous testing and code reviews to identify and fix potential bugs and ensure that the changes did not negatively impact the existing functionality of the codebase.\n\nAdditionally, extensive test coverage was put in place to ensure that the new feature worked as expected and did not cause unintended side effects. The team utilized GitLab's [test coverage visualization](https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html) capabilities to track the extent of test coverage and identify areas that required additional testing.\n\n![PIPE](https://about.gitlab.com/images/blogimages/remote-development/PIPE.png){: .shadow.medium}\n\n## The merging process\nAs part of the Remote Development team, we took a strategic approach to the merging process. We identified three categories of follow-up tasks that needed to be addressed after the release:\n\n1. **To-dos:** This category encompassed follow-up issues that required further attention.\n2. **Disabled linting rules:** Any issues related to disabled linting rules were included in this category.\n3. **Follow-up from review:** Non-blocking concerns raised during the review process were categorized here.\n\nTo manage this process effectively, we organized these categories into [child epics](https://docs.gitlab.com/ee/user/group/epics/manage_epics.html#multi-level-child-epics) under the main epic representing the merging effort.\n\n1. Child epic for [to-do follow-up issues](https://gitlab.com/groups/gitlab-org/-/epics/10472)\n2. Child epic for [disabled linting rules follow-up issues](https://gitlab.com/groups/gitlab-org/-/epics/10473)\n3. Child epic for [follow-up issues from review](https://gitlab.com/groups/gitlab-org/-/epics/10474)\n\n\n## Reviewer resources\nDuring the integration branch merge process for the Remote Development feature, we ensured a smooth and collaborative review experience for all involved. To facilitate this, we set up the following resources and documented the information in GitLab's issue, epic, and MR reviews for better persistence and traceability:\n\n1. **Dedicated Slack channel:** We had a Slack channel that served as our primary hub for coordinating reviews and resolving any blockers that arose during the process. The discussions, decisions, and important points discussed in this channel were documented in the related GitLab issues and epics. This approach enabled us to maintain a historical record of the conversations for to refer back to in the future.\n2. **General Slack channel:** For non-urgent or non-blocking questions and discussions, reviewers could use the a general Slack channel. Similar to the dedicated channel, we documented the relevant information from this channel in the corresponding issues and MR reviews in GitLab.\n3. **Addressing urgent issues:** When urgent issues required immediate attention, reviewers could directly address our technical leads [Vishal Tak](https://gitlab.com/vtak) and/or [Chad Woolley](https://gitlab.com/cwoolley-gitlab) in their Slack messages. However, we kindly requested that [direct messages were avoided](https://handbook.gitlab.com/handbook/communication/#avoid-direct-messages) to promote open collaboration. The resolutions to these urgent issues were documented in the corresponding GitLab issues or MR discussions.\n4. **Zoom collaboration room:** The collaborative sessions held in the open Zoom room were not only beneficial for real-time discussions but also for fostering a collaborative environment. After each session, we summarized the key points and decisions made during the meeting in the associated GitLab issue or MR, making sure all important outcomes were captured and accessible to the team.\n\nThroughout the review process, we were committed to maintaining a seamless and well-documented workflow. By capturing all relevant information in GitLab issues, epics, and MR reviews, we ensured that the knowledge was persistently available, and future team members could easily understand the context and decisions made during the integration process.\n\n## Application security review\nDuring the application security review process, we focused on providing a secure and reliable Remote Development feature for our users. Here are the key resources and updates related to the application security review:\n\n1. **Main application security review issue:** The main application security review issue served as the central hub for tracking security-related considerations. You can find the defined process we followed [here](https://about.gitlab.com/handbook/security/security-engineering/application-security/appsec-reviews.html).\n2. **Application security review comment:** The application security review issue contained a comment indicating that the merge was not blocked unless there were severe issues that could impact production. \"In order to maintain a smooth merge process, we do not block MRs from being merged unless we identify severe issues that could prevent the feature from going into production, such as S1 or S2 level problems. If you are aware of any design flaws or concerns that might qualify as such issues, please bring them to our attention. We can review them together and address any questions or concerns that arise. Let's work collaboratively to find an approach that works for both parties. 👍\"\n3. **Engineering perspective:** For managing the application security review process from an engineering team perspective, we had a dedicated issue, which is kept confidential for security reasons.\n4. **Security and authentication matters:** All security and authentication concerns pertaining to the Beta release were documented within the [`Remote Development Beta -Auth` epic](https://gitlab.com/groups/gitlab-org/-/epics/10377). As of April 30, 2023, we are delighted to announce that **no known issues or obstacles were found that would impede the merge**. This represents a significant accomplishment, considering the intricate nature of this new feature.\n5. **Initial question raised:** During the application security review, one initial question was raised, and we promptly addressed it. You can track the issue and our response [here](https://gitlab.com/gitlab-org/gitlab/-/issues/409317).\n\n## Database review\nTo ensure the reliability and efficiency of the Remote Development feature, we sought guidance from the database reviewer. Although the team had not conducted a thorough self-review, we were fully prepared to address any blocking issues raised during the review process. Our references for the review were:\n\n- [Database review documentation](https://docs.gitlab.com/ee/development/database_review.html)\n- [Database reviewer guidelines](https://docs.gitlab.com/ee/development/database/database_reviewer_guidelines.html)\n\nAs an example, during the database migration review, a discussion arose between [Alper Akgun](https://gitlab.com/a_akgun) and Chad, regarding the efficient ordering of columns in the workspaces table. Alper initially suggested placing integer values at the beginning of the table based on relevant documentation.\n\nChad questioned the benefit of this suggestion, pointing out that the specific integer field, `max_hours_before_termination`, would still be padded with empty bytes even if moved to the front, due to its current position between two text fields.\n\nAlper proposed an alternative approach, emphasizing that organizing variable-sized fields (such as `text`, `varchar`, `arrays`, `json`, `jsonb`) at the end of the table could be sufficient for the workspaces table.\n\nUltimately, Chad took the initiative to implement the changes, moving all variable length fields to the end of the table, and documented the discussion as a comment to address review suggestions.\n\nWith this collaborative effort, the workspaces table was efficiently optimized, and the team gained valuable insights into database column ordering strategies.\n\n![DB](https://about.gitlab.com/images/blogimages/remote-development/DB.png){: .shadow.medium}\n\n## Ruby code review\nDuring the Ruby code review phase, we followed a meticulous approach by conducting a comprehensive self-review of every line of code. Our goal was to ensure the highest code quality and address any potential issues identified by the reviewers effectively.\n\nTo ensure clarity, it's important to clarify that the Ruby code review primarily focused on backend changes and server-side improvements. This included optimizing performance, enhancing functionalities, and refining the overall codebase to deliver a seamless user experience.\n\nFor the code review process, we referred to the [Code review documentation](https://docs.gitlab.com/ee/development/code_review.html), a valuable resource that guided us in maintaining industry best practices and adhering to the GitLab community's coding standards.\n\n### Example: Enhance error messages for unavailable features\nAs an example during the code review, we addressed an essential aspect of the workspace method, focusing on how we handle scenarios related to the `remote_development_feature_flag` and the `remote_development` licensed feature. The primary objective was to enhance the error messages presented to users when these features are not available.\n\nInitially, the code employed identical error messages for both cases, making it less clear to users whether the issue was due to a missing license or a disabled feature flag. This ambiguity could lead to confusion and hinder the user experience.\n\n#### The suggested improvement\nDuring the review, one of our maintainers, [Peter Leitzen](https://gitlab.com/splattael), raised an important question: \"Are we OK with having only a single error message for both cases (missing license and missing feature flag)?\"\n\nRecognizing the importance of clear communication, Chad proposed enhancing the error messages to provide distinct descriptions for each case. This improvement aimed to empower users by precisely conveying the reason behind the unavailability of certain features.\n\n#### The revised implementation\nFollowing Chad's suggestion, the code underwent the following changes:\n\n```ruby\nunless ::Feature.enabled?(:remote_development_feature_flag)\n  # TODO: Could have `included Gitlab::Graphql::Authorize::AuthorizeResource` and then use\n  #       raise_resource_not_available_error!, but didn't want to take the risk to mix that into\n  #       the root query type\n  raise ::Gitlab::Graphql::Errors::ResourceNotAvailable,\n    \"'remote_development_feature_flag' feature flag is disabled\"\nend\n\nunless License.feature_available?(:remote_development)\n  # TODO: Could have `included Gitlab::Graphql::Authorize::AuthorizeResource` and then use\n  #       raise_resource_not_available_error!, but didn't want to take the risk to mix that into\n  #       the root query type\n  raise ::Gitlab::Graphql::Errors::ResourceNotAvailable,\n    \"'remote_development' licensed feature is not available\"\nend\n\nraise_resource_not_available_error!('Feature is not available') unless current_user&.can?(:read_workspace)\n```\n\n#### The value of distinct error messages\nBy implementing distinct and descriptive error messages, we reinforce our commitment to user-centric development. Users interacting with our system will receive accurate feedback, helping them navigate potential roadblocks effectively. This enhancement not only improves the user experience but also streamlines troubleshooting and support processes.\n\nThis code review example highlights the significance of concise and informative error messages in delivering a top-notch user experience within the GitLab ecosystem. Our team's collaborative efforts ensure that users can confidently interact with our platform, knowing they'll receive clear and helpful error messages when needed.\n\n![BE1](https://about.gitlab.com/images/blogimages/remote-development/BE1.png){: .shadow.medium}\n\n### Example: Improving performance and addressing N+1 issues in WorkspaceType\nIn a recent code review, our team focused on optimizing the WorkspaceType and addressing potential N+1 query problems. The discussion involved two key contributors, [Laura Montemayor](https://gitlab.com/lauraX) and Chad, who worked together to enhance the performance of the codebase.\n\n#### Identifying the performance concerns\nDuring the review, Laura raised a performance concern regarding the possibility of N+1 queries in the WorkspaceType resolver. She suggested that preloading certain associations could be beneficial to avoid this common performance issue.\n\n#### A separate issue for N+1 control\nChad took prompt action and created a separate issue specifically aimed at resolving the N+1 query problems. The new issue, titled \"Address review feedback: Resolve N+1 issues,\" would address the concerns raised by Laura and implement the necessary preloading.\n\n#### Evaluating the potential N+1 impact\nChad provided insightful information about the low risk of real N+1 impact from two particular fields in the current implementation. He elaborated on how the queries for user and agent associations would largely be cache hits due to scoping and usage patterns. Chad diligently examined the cache hits happening in development, confirming the potential optimization.\n\nHere's a code snippet from the initial implementation:\n\n```ruby\n# Initial Implementation\nclass WorkspaceType \u003C BaseType\n  field :user, ::Types::UserType,\n    description: \"User associated with this workspace\",\n    null: true\n\n  field :agent, ::Types::AgentType,\n    description: \"Agent associated with this workspace\",\n    null: true\n\n  # Resolver for the user association\n  def user\n    object.user\n  end\n\n  # Resolver for the agent association\n  def agent\n    object.agent\n  end\nend\n```\n\n#### Treating performance as a priority\nBoth contributors acknowledged the significance of addressing the performance concern, with Laura emphasizing its importance. They agreed to prioritize the separate issue dedicated to resolving the N+1 queries and ensuring proper test coverage.\n\nHere's a code snippet from the revised implementation:\n\n```ruby\n# Revised Implementation with Preloading\nclass WorkspaceType \u003C BaseType\n  field :user, ::Types::UserType,\n    description: \"User associated with this workspace\",\n    null: true\n\n  field :agent, ::Types::AgentType,\n    description: \"Agent associated with this workspace\",\n    null: true\n\n  # Resolver for the user association with preloading\n  def user\n    ::Dataloader.for(::User).load(object.user_id)\n  end\n\n  # Resolver for the agent association with preloading\n  def agent\n    ::Dataloader.for(::Agent).load(object.agent_id)\n  end\nend\n```\n\n#### Considering future usage\nChad expressed excitement about the possibility of the new feature gaining significant usage. He humorously stated that encountering enough legitimate traffic on workspaces to trigger any performance impact would be a delightful problem to have, as it would indicate a growing user base.\n\n#### Collaboration and performance improvement\nThe code review exemplifies the collaborative and proactive approach of our team in optimizing the WorkspaceType. The team's dedication to addressing performance concerns ensures that our codebase remains performant and efficient, even as our user base grows.\n\n![BE2](https://about.gitlab.com/images/blogimages/remote-development/BE2.png){: .shadow.medium}\n\n## Frontend code review\nThe frontend code review process was managed by our resident `Create: IDE` frontend maintainers, [Paul Slaughter](https://gitlab.com/pslaughter) and [Enrique Alcátara](https://gitlab.com/ealcantara). Additionally, a significant portion of the new frontend UI code had already undergone separate reviews and was merged to master, contributing to the overall quality of the Remote Development feature.\n\n### Example: Collaborative code improvement for ApolloCache Mutators\nPaul started a thread on an old version of the diff related to `ee/spec/frontend/remote_development/pages/create_spec.js``. The code snippet in question involved creating a mock Apollo instance and writing queries to the cache.\n\n#### The initial implementation\nInitially, the code involved writing to the cache twice, which raised concerns among the maintainers, Paul and Enrique. Paul pointed out that the duplicate write was unintentional and wondered if the writeQuery was even necessary, given the removal of @client directives. However, he also acknowledged the need to test that the created workspace was added to the ApolloCache.\n\n```javascript\n// Initial Implementation\nconst buildMockApollo = () => {\n  // ... Other mock setup ...\n\n  // Initial writeQuery for userWorkspacesQuery\n  mockApollo.clients.defaultClient.cache.writeQuery({\n    query: userWorkspacesQuery,\n    data: USER_WORKSPACES_QUERY_EMPTY_RESULT.data,\n  });\n\n  // ... Other mock setup ...\n};\n```\n\n#### Identifying a potential issue\nEnrique agreed that the duplicate write was unintentional and probably introduced during a rebase. He explained that pre-populating the cache with a user workspaces query empty result was essential for the mutator to have a place to add the workspace. However, he encountered difficulties in making the workaround work effectively in unit tests.\n\n#### Resolving the issue\nPaul highlighted the significance of pre-populating the cache with the user workspaces query empty result. He suggested leaving a comment to explain the necessity of the initial writeQuery, as it would be implicitly coupled to future writeQuery operations.\n\n```javascript\n// Resolving the Issue - Leaving a Comment\n// Pre-populate the cache with user workspaces query empty result to provide a place\n// for the mutator to add the Workspace later. This is needed for both test and production environments.\nmockApollo.clients.defaultClient.cache.writeQuery({\n  query: userWorkspacesQuery,\n  data: USER_WORKSPACES_QUERY_EMPTY_RESULT.data,\n});\n```\n\nHowever, upon further investigation, Paul discovered that the writeQuery might not be needed, and the issue might be a symptom of an underlying problem. He decided to open a separate thread to address this concern and indicated that he would work on a separate MR to handle it.\n\n```javascript\n// Resolving the Issue - Opening a Separate Thread and MR\n// Open a separate thread to discuss potential underlying issues.\n// Plan to work on a separate MR to handle it.\n// Stay tuned for updates!\n```\n\n![FE](https://about.gitlab.com/images/blogimages/remote-development/FE.png){: .shadow.medium}\n\n## What we learned\nAs part of the Remote Development team, we faced the challenge of merging the Remote Development Rails monolith integration branch to meet our ambitious release goal. We adapted to last-minute pivots and focused on minimizing risks during the review process. The successful merge brought us one step closer to benefiting GitLab users worldwide. We acknowledged areas for improvement and remained committed to refining the feature's quality. Our journey reflects our dedication to delivering results, embracing change, and pushing boundaries in the DevOps community. The release of the Remote Development feature in GitLab 16.0 is a significant milestone for GitLab, and we continue to iterate and grow, providing innovative solutions for developers worldwide.\n\nAn outcome of this process was an ongoing conversation to propose a [simplified review process for greenfield features](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125117). Through this proposal, we aim to distill the lessons we learned during this experience and provide guidance to future teams facing similar challenges.\n\n## What is next for Remote Development?\nAfter the merge of the MR, several changes were implemented:\n- The first production tests were conducted to ensure the stability and functionality of the merged code.\n- Collaboration took place between the Dev Evangelism and Technical Marketing teams, focusing on [creating content](https://gitlab.com/groups/gitlab-com/marketing/developer-relations/-/epics/190). This collaboration aimed to troubleshoot any issues that arose during the merge.\n- Feedback from the community was taken into account, and changes were made to address the concerns raised. This feedback was incorporated into an [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/410031) and influenced the overall roadmap and direction of the project.\n\nDo you want to [contribute to GitLab](/community/contribute/)? Come and join in the conversation in the `#contribute` channel on GitLab's [Discord](https://discord.gg/gitlab), or just pop in and say \"Hi.\"\n\n",[827,9,1016,953,3268,803],"contributors",{"slug":3270,"featured":6,"template":698},"remote-development-beta","content:en-us:blog:remote-development-beta.yml","Remote Development Beta","en-us/blog/remote-development-beta.yml","en-us/blog/remote-development-beta",{"_path":3276,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3277,"content":3283,"config":3290,"_id":3292,"_type":14,"title":3293,"_source":16,"_file":3294,"_stem":3295,"_extension":19},"/en-us/blog/revisiting-the-variables-management-workflow",{"title":3278,"description":3279,"ogTitle":3278,"ogDescription":3279,"noIndex":6,"ogImage":3280,"ogUrl":3281,"ogSiteName":686,"ogType":687,"canonicalUrls":3281,"schema":3282},"Revisiting the variables management workflow","Our users helped us identify the hurdles in the variables management experience and we used those insights to guide improvements.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098484/Blog/Hero%20Images/Blog/Hero%20Images/AdobeStock_618473457_nd5Dr8kfGdrlTWLOPmDjb_1750098483284.jpg","https://about.gitlab.com/blog/revisiting-the-variables-management-workflow","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Revisiting the variables management workflow\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Veethika Mishra\"}],\n        \"datePublished\": \"2024-02-26\",\n      }",{"title":3278,"description":3279,"authors":3284,"heroImage":3280,"date":3286,"body":3287,"category":909,"tags":3288},[3285],"Veethika Mishra","2024-02-26","CI/CD variables play a vital role in building and maintaining CI/CD pipelines and platforms. They are an essential part of the majority of developers’ workflows, serving a range of purposes from storing reusable information to maintaining data integrity. Given their significance, we made enhancing workflows related to CI/CD variables a priority.\nRecently, we conducted interviews with users representing different [personas](https://handbook.gitlab.com/handbook/product/personas/#list-of-user-personas) related to software development, working in teams with different structural and cultural dynamics. Our aim was to gain insights into the challenges they encounter when using and managing CI/CD variables within GitLab. The feedback helped us gain valuable perspective, guiding us toward [necessary improvements](https://gitlab.com/gitlab-org/gitlab/-/issues/418331) in these workflows. Some of the notable changes are highlighted in this blog.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/gdL2cEp3kw0?si=aNmhofDU3DsnofiP\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Better management\n\n![variables management - image 1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098505/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098504762.png)\n\nEffective decision-making regarding the addition, modification, or removal of CI/CD variables hinges on understanding their purpose within a project or group. Lacking visibility into a variable's purpose can complicate these decisions. To address this challenge, we've introduced an enhancement to the variable creation process that will allow users to provide a description detailing the usage and context of a variable, reducing reliance on memory. This description will be displayed in the list, along with the other attributes of the variable. \n\n## Seamless task continuity\n\n![variables management - image 2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098505/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750098504763.png)\n\nEfficiency is paramount in software development as it allows developers to make time to focus on qualitative aspects of their work. We have changed the variable creation workflow to facilitate consecutive addition or editing of multiple variables to boost efficiency. Improved, clear notifications and contextual error messages ensure users can perform tasks without the need to repeatedly open separate forms.\n\n## Enhanced error prevention\n\n![variables management - image 3](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098505/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098504764.png)\n\nHow the error messages are presented and made accessible in a workflow determines their effectiveness in error resolution. We revisited the different error states users are likely to encounter during variable creation and editing workflow and identified the improvement opportunities ranging from adding new validations and help-texts to enhancing existing error-handling states.\n\n## Share your feedback\nWe believe in taking an iterative approach to better the product. We used insights from the recent user research and our best judgment when deciding on the changes, but there’s always room for improvement. Your feedback from your experience of using the changed UI for performing the tasks in your everyday work will help us understand what’s working and what isn’t, and, therefore, decide on future iterations. Please head to our [feedback issue](https://gitlab.com/gitlab-org/gitlab/-/issues/441177) to share your thoughts and suggestions on the changes made.\n\n## What’s next?\nAs we work on making the existing variables workflow more usable, we’re also making progress on the [GitLab Secret Manager](https://about.gitlab.com/direction/govern/pipeline_security/secrets_management/#overview) to provide users with a more secure method for enabling GitLab, or a component built within GitLab, to connect to other systems.\n\nThere’s an ongoing effort to [improve the variables table layout to clearly represent the visual hierarchy](https://gitlab.com/gitlab-org/gitlab/-/issues/403176) between group and project variables and enhancing the [audit history for CI variables](https://gitlab.com/gitlab-org/gitlab/-/issues/416148) to provide better visibility into activities related to variables.\n\n## Read more about our UI improvements\n- [How we overhauled GitLab navigation](https://about.gitlab.com/blog/navigation-research-blog-post/)\n- [Beautifying our UI: Giving GitLab build features a fresh look](https://about.gitlab.com/blog/beautifying-of-our-ui/)\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[109,3289,9,1299],"UX",{"slug":3291,"featured":91,"template":698},"revisiting-the-variables-management-workflow","content:en-us:blog:revisiting-the-variables-management-workflow.yml","Revisiting The Variables Management Workflow","en-us/blog/revisiting-the-variables-management-workflow.yml","en-us/blog/revisiting-the-variables-management-workflow",{"_path":3297,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3298,"content":3303,"config":3308,"_id":3310,"_type":14,"title":3311,"_source":16,"_file":3312,"_stem":3313,"_extension":19},"/en-us/blog/rise-of-protestware",{"title":3299,"description":3300,"ogTitle":3299,"ogDescription":3300,"noIndex":6,"ogImage":1449,"ogUrl":3301,"ogSiteName":686,"ogType":687,"canonicalUrls":3301,"schema":3302},"Protestware threats: How to protect your software supply chain","Some people protest for change by changing code others depend on throughout the software supply chain. Learn more about protestware, its impact, and how to protect against it.","https://about.gitlab.com/blog/rise-of-protestware","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Protestware threats: How to protect your software supply chain\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Abubakar Siddiq Ango\"}],\n        \"datePublished\": \"2023-05-09\",\n      }",{"title":3299,"description":3300,"authors":3304,"heroImage":1449,"date":3305,"body":3306,"category":10,"tags":3307},[1455],"2023-05-09","In 2016, the continuous integration (CI) pipelines of millions of projects\nfailed because a developer decided to pull their projects from npm package\nregistry in [protest of a request to take down or rename one of their\npackages](https://www.theregister.com/2016/03/23/npm_left_pad_chaos/). In\nJanuary 2022, the maintainer of the widely used 'colors' and 'faker'\npackages on the npm registry modified [these\nprojects](https://blog.sonatype.com/npm-libraries-colors-and-faker-sabotaged-in-protest-by-their-maintainer-what-to-do-now?hsLang=en-us),\nadding malicious code that infinitely printed gibberish in protest of\ncorporations who use open source projects without giving back. These are two\nexamples of \"protestware,\" a term that refers to software packages or\napplications that have been intentionally modified to send a political\nmessage. The impacts may range from seeing unexpected messages in a terminal\nor logs when building an application to serious adverse impacts like data\ndeletion. \n\n\nWhile protestware remained rare for a long time, recent high-profile\nincidents have brought it back into the spotlight. Similar code injection\nvariants like\n[typosquatting](https://www.kaspersky.com/resource-center/definitions/what-is-typosquatting)\npackages (as in the case of the [colors\nnpm](https://www.mend.io/resources/blog/new-typosquating-attack-on-npm-package-colors-using-cross-language-technique-explained/)\npackage, where bad actors created compromised clones of packages with\nsimilar names) and compromised packages (as in the case of the [ctx PyPI\npackages](https://www.theregister.com/2022/05/24/pypi_ctx_package_compromised/))\nare usually perpetrated by bad actors looking to cause harm. Protestware is\nunusual in that the custodians of projects trusted by the community have\nallowed or made these changes. Regardless of whether the changes' impacts\nare harmful, such changes raise ethical concerns and can create unwanted\ndistractions. These risks also reinforce the need for open source consumers\nto adopt a [zero trust security\nmodel](/blog/why-devops-and-zero-trust-go-together/) for their\nsoftware supply chain. Trust, but verify!\n\n\nThe world is going through unprecedented movements demanding change, and\nchange seekers will find new and often disruptive ways to be heard, as we\nhave seen in the case of everything from climate activism to TikTok\nchallenges. Software supply chains are not exempt and, as we have learned\nfrom past incidents, being proactive is key to staying secure.\n\n\nHere are some steps you can take to protect your software supply chain by\nensuring your dependencies are secure.\n\n\n## Implement dependency scanning\n\n\n[Dependency\nscanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/)\nis now an industry standard, and there is no shortage of tools or libraries\nto scan your packages, containers, or any other binary formats for\nvulnerabilities. Using GitLab CI’s\n[`rules:exists`](https://docs.gitlab.com/ee/ci/yaml/#rulesexists) rule,\nGitLab checks for the presence of certain files to determine the appropriate\nscans to check for vulnerabilities. Coupled with [Vulnerability\nReports](https://docs.gitlab.com/ee/user/application_security/vulnerability_report/),\n[Policy\nManagement](https://docs.gitlab.com/ee/user/application_security/policies/index.html#policy-management),\nand the [Security\nDashboard](https://docs.gitlab.com/ee/user/application_security/security_dashboard/index.html),\nyour security team and organization can stay ahead of vulnerabilities. To\ninclude dependency scanning in your CI pipeline, add the following lines to\nyour `.gitlab-ci.yml` file. You can explore the [Dependency Scanning CI\ntemplate](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml)\nto understand how it works. \n\n\n```\n\n\ninclude:\n\n  template: Jobs/Dependency-Scanning.gitlab-ci.yml\n\n```\n\n\nRunning the CI script against an example [Ruby on Rails\nproject](https://gitlab.com/gitlab-de/playground/ruby-rails-demo) with Ruby\n3.0.4, the [Vulnerability\nReport](https://gitlab.com/gitlab-de/playground/ruby-rails-demo/-/security/vulnerability_report/?scanner=GitLab.DEPENDENCY_SCANNING)\nshows more than 70 vulnerabilities detected for the dependencies in the\nproject’s\n[Gemfile](https://gitlab.com/gitlab-de/playground/ruby-rails-demo/-/blob/master/Gemfile).\n\n\n\n![Vulnerability Report\nImage](https://about.gitlab.com/images/blogimages/2023-04-rise-of-protestware/vulnerability-report.png\n\"Vulnerability Report Image\")\n\n\n\n## Generate provenance validations\n\n\nUsers of packages can verify they are not downloading a compromised version\nusing [artifact\nattestation](https://docs.gitlab.com/ee/ci/runners/configure_runners.html#artifact-attestation),\nwhich was [introduced in GitLab Runner\n15.1](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/28940/).\nAttestation metadata is generated in the [in-toto\nformat](https://github.com/in-toto/attestation); it provides\n[provenance](https://slsa.dev/provenance/v0.2) attesting to how a binary was\nbuilt, and you can verify the artifacts against the provenance. This allows\nyou to achieve [Level\n2](/blog/achieve-slsa-level-2-compliance-with-gitlab/) of the\nSupply-chain Levels for Software Artifacts ([SLSA](https://slsa.dev/))\nsecurity framework. \n\n\nThe demo video below shows how to configure your CI script to generate\nartifact attestation metadata.\n\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/MlIdqrDgI8U\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\n\n## Utilize private registries\n\n\n[Self-hosting registries](https://docs.gitlab.com/ee/user/packages/) for\npackages, container images, or your Terraform modules are a more secure way\nof ensuring secure and vetted packages are used by your team. Security and\ncompliance teams are enabled to ensure total control of the dependencies\nused in the entire organization and how they are accessed with [package\nregistry\npermissions](https://docs.gitlab.com/ee/user/packages/package_registry/index.html#package-registry-visibility-permissions).\nGitLab supports container, infrastructure, and package registries. Package\nregistries supported include Composer (PHP), Conan (C/C++), Generic, Maven\n(Java), npm (NodeJS), NuGet (Windows packaging), PyPI (Python), and RubyGems\n(Ruby).\n\n\n## Enable Dependency Proxy\n\nThe [Dependency\nProxy](https://docs.gitlab.com/ee/user/packages/dependency_proxy/index.html)\nreduces the number of requests made to upstream dependency registries by\nacting as a local proxy. This reduces the impact of changes or\nvulnerabilities in the upstream packages, as a clean version will still be\nstored in the Dependency Proxy’s cache. This offers faster build times,\nsince the cache is most likely closer to the build system that needs the\nimage, and it ensures continuity when an upstream registry is having\ndowntime or enforcing rate limits — as in the case of [Docker\nHub](https://docs.docker.com/docker-hub/download-rate-limit/), which has a\nlimit of 100 container image pulls per 6 hours per IP address container\nimage for anynomous users as of the time of writing this article.\n\n\nYou can enable Dependency Proxy in the Packages and Registries section of a\ngroup’s settings. Only an administrator can enable/disable the Dependency\nProxy for a GitLab instance. \n\n\n![Dependency Proxy setting\nimage](https://about.gitlab.com/images/blogimages/2023-04-rise-of-protestware/dependency-proxy.png\n\"Dependency Proxy Setting Image\")\n\n\n\nTo use the Dependency Proxy in your CI script, you can use the\n`CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX` predefined variable as shown below:\n\n\n```\n\n\n# .gitlab-ci.yml\n\n\nimage: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/ubuntu:latest\n\n\n```\n\n\nThe GitLab Runner automatically authenticates with the Dependency Proxy, but\nif your use case requires manual authentication, like building container\nimages, you can use other predefined CI/CD variables as detailed in the\n[documentation](https://docs.gitlab.com/ee/user/packages/dependency_proxy/index.html).\n\n\nGitLab is also working on leveraging the Dependency Proxy to give more\ncontrol to security teams with the [Dependency\nFirewall](https://about.gitlab.com/direction/package/#dependency-firewall),\nwhich will allow for control of how upstream packages are used and how they\nimpact the organization. Package validation and version management can be\nmanaged from a central location without impacting the workflow of users.\n\n\nProactively instrumenting your software development lifecycle to ensure\ncontinuous review of your application along with controls is critical to\nkeeping your software supply chain secure and preventing production problems\ndue to protestware.\n",[9,2294,694,496],{"slug":3309,"featured":6,"template":698},"rise-of-protestware","content:en-us:blog:rise-of-protestware.yml","Rise Of Protestware","en-us/blog/rise-of-protestware.yml","en-us/blog/rise-of-protestware",{"_path":3315,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3316,"content":3322,"config":3328,"_id":3330,"_type":14,"title":3331,"_source":16,"_file":3332,"_stem":3333,"_extension":19},"/en-us/blog/seamlessly-migrate-from-jira-to-gitlab-with-jira2lab-at-scale",{"title":3317,"description":3318,"ogTitle":3317,"ogDescription":3318,"noIndex":6,"ogImage":3319,"ogUrl":3320,"ogSiteName":686,"ogType":687,"canonicalUrls":3320,"schema":3321},"Seamlessly migrate from Jira to GitLab with Jira2Lab at scale","Discover how Jira2GitLab simplifies large-scale Jira-to-GitLab migrations by handling complex data transfers, improving scalability, and ensuring efficient integration.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663129/Blog/Hero%20Images/blog-image-template-1800x945__28_.png","https://about.gitlab.com/blog/seamlessly-migrate-from-jira-to-gitlab-with-jira2lab-at-scale","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Seamlessly migrate from Jira to GitLab with Jira2Lab at scale\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Maximilien Belinga\"}],\n        \"datePublished\": \"2024-10-10\",\n      }",{"title":3317,"description":3318,"authors":3323,"heroImage":3319,"date":3325,"body":3326,"category":1397,"tags":3327},[3324],"Maximilien Belinga","2024-10-10","[Atlassian Server reached end of life in February](https://about.gitlab.com/move-to-gitlab-from-atlassian/), prompting many customers to explore alternatives like Atlassian Cloud or Data Center. However, enterprises using Atlassian Server are increasingly seeking Agile planning solutions that offer more flexibility, cost-efficiency, and robust DevSecOps integration. They also need to tackle challenges related to data volume, customization, user mapping, performance, and data integrity during migration. This is where [GitLab’s Jira2Lab](https://gitlab.com/gitlab-org/professional-services-automation/tools/migration/jira2lab) comes into play, offering a seamless solution for large-scale Jira migrations to GitLab, while providing full CI/CD integration.\n\n## The problem with large-scale Jira migrations\n\nMigrating from Jira to GitLab can be a significant hurdle, especially for enterprises with complex workflows and thousands of issues to move. Here are the most common challenges faced during such migrations:\n\n- **Massive data migration:** As the number of issues, attachments, comments, and projects increases, so does the complexity of migrating them without performance issues or data loss.\n\n- **Custom fields and workflows:** Jira instances often contain custom workflows, fields, and issue types that do not have a one-to-one mapping in GitLab. This gap creates friction during migration, as existing tools often require manual intervention to translate these elements.\n\n- **Lack of full DevSecOps integration:** While many migration tools handle project management data, they do not integrate GitLab’s full DevSecOps capabilities. As a result, teams are left to manually configure their [CI/CD](https://about.gitlab.com/topics/ci-cd/) pipelines and source control management systems after the migration.\n\n## Introducing Jira2Lab\n\nJira2Lab was designed from the ground up to solve the specific challenges of migrating from Jira to GitLab at scale. It’s not just about moving data; it’s about enabling teams to seamlessly transition into GitLab’s powerful DevSecOps environment without downtime or data loss.\n\n### Key features of Jira2Lab\n\n1. Efficient data handling at scale\u003Cbr> \nJira2Lab is optimized to handle thousands of issues, attachments, comments, and custom fields across multiple projects without sacrificing performance. It scales effortlessly to accommodate even the largest enterprise migrations.\n\n2. Custom workflow and field mapping\u003Cbr>\nOne of the standout features of Jira2Lab is its ability to automatically map custom workflows and fields from Jira to GitLab. The tool provides a flexible mapping configuration that eliminates the need for manual intervention during the migration process, making sure everything moves smoothly from Jira to GitLab.\n\n3. CI/CD pipeline integration\u003Cbr>\nJira2Lab doesn’t just migrate your issues and projects — it integrates GitLab’s full CI/CD pipeline into the migration process. This ensures that development teams can start using GitLab’s DevSecOps features, such as automated testing and deployment pipelines, immediately after migration.\n\n4. Pilot migrations\u003Cbr>\nOur tool supports pilot migrations to allow teams to test their configurations and workflows before scaling up. This ensures that any issues can be caught early, preventing disruptions during the full migration.\n\n5. Real-time monitoring\u003Cbr>\nThe tool provides real-time monitoring and logs during migration, giving complete transparency to ensure every step is performed correctly and without errors.\n\n6. Customizable and flexible\u003Cbr>\nEven if your Jira instance has unique configurations or workflows, Jira2Lab offers the flexibility to customize the migration according to your specific requirements, ensuring nothing is lost in translation.\n\n### Feature comparison: Jira vs. GitLab\n\nMigrating from Jira to GitLab helps consolidate workflows and unlock advanced features native to GitLab. Here’s a quick comparison of the core features of both platforms:\n\n| **Feature**             | **Jira**                        | **GitLab**                    |\n|-------------------------|----------------------------------|-------------------------------|\n| **Issue Tracking**       | Yes (Highly customizable)       | Yes (Integrated with DevSecOps)   |\n| **Agile Boards**         | Yes (Kanban, Scrum)             | Yes (Issue Boards, Milestones) |\n| **CI/CD**                | No (Requires external tools)    | Yes (Built-in CI/CD)           |\n| **Source Control**       | No (Requires GitHub/Bitbucket)  | Yes (Native Git support)       |\n| **DevSecOps Tools**         | Limited integrations            | Full DevSecOps lifecycle          |\n\nWith Jira2Lab, we ensure that all critical aspects, from issue tracking to CI/CD pipelines, are transitioned smoothly, taking full advantage of GitLab’s integrated approach to development and operations.\n\n## The migration methodology\n\nJira2Lab follows a structured, five-phase migration methodology, ensuring seamless transition with minimal disruption:\n\n### 1. Discovery and planning\n\nWe start by thoroughly understanding the customer’s Jira setup, identifying all necessary custom workflows, fields, and projects that need to be migrated. This phase also involves a gap analysis to compare Jira and GitLab features and map out the migration process.\n\n### 2. Setup\nIn this phase, we configure the migration tool and set up the necessary environments for both Jira and GitLab. This includes verifying all permissions and setting up a backup of Jira data before the migration begins.\n\n### 3. Pilot migrations\nBefore migrating the entire dataset, we run pilot migrations on selected projects to test the migration process, workflows, and data integrity. This allows us to identify and resolve any issues early in the process.\n\n### 4. Scaled migrations\nAfter validating the pilot migration, we scale the migration across all projects, ensuring minimal downtime and smooth transitions for development teams.\n\n### 5. Wrap-up and post-migration support\nOnce the migration is complete, we provide ongoing support, ensuring all teams are fully operational in GitLab. This phase also includes user training and the decommissioning of the Jira instance, if required.\n\n## Case study: Tackling scale with Jira2Lab\n\nIn a recent migration, a large enterprise faced the challenge of migrating over 20,000 issues across 50 projects from Jira to GitLab. The project had highly customized workflows and thousands of comments and attachments that needed to be transferred.\n\nWith Jira2Lab, we were able to:\n\n- Migrate all data, including custom fields, without any data loss.\n- Set up CI/CD pipelines within GitLab so that teams could immediately continue their work post-migration.\n- Conduct a pilot migration of two projects, which allowed us to identify and fix minor workflow discrepancies before scaling up to the entire organization.\n\nThe result was a seamless transition to GitLab, with the entire process completed within the planned timeline and no significant downtime.\n\n## Get started with Jira2Lab today\n\nJira2Lab stands out in the market by addressing the limitations that other migration tools cannot handle. It is designed specifically for large-scale migrations and can integrate with GitLab’s full DevSecOps lifecycle, unlike most tools that only handle project management data. The tool’s ability to map custom workflows and integrate CI/CD pipelines makes it the perfect solution for enterprises looking to enhance their development workflows while migrating to GitLab.\n\n> Ready to scale your development processes with GitLab? Explore our [Professional Services catalog](https://about.gitlab.com/services/catalog/) to learn how we can help your team migrate efficiently and effectively. Contact us through the form at the end for a personalized demo of GitLab's Jira2Lab.\n",[1399,109,9,719,848],{"slug":3329,"featured":91,"template":698},"seamlessly-migrate-from-jira-to-gitlab-with-jira2lab-at-scale","content:en-us:blog:seamlessly-migrate-from-jira-to-gitlab-with-jira2lab-at-scale.yml","Seamlessly Migrate From Jira To Gitlab With Jira2lab At Scale","en-us/blog/seamlessly-migrate-from-jira-to-gitlab-with-jira2lab-at-scale.yml","en-us/blog/seamlessly-migrate-from-jira-to-gitlab-with-jira2lab-at-scale",{"_path":3335,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3336,"content":3342,"config":3348,"_id":3350,"_type":14,"title":3351,"_source":16,"_file":3352,"_stem":3353,"_extension":19},"/en-us/blog/secure-by-design-principles-meet-devsecops-innovation-in-gitlab-17",{"title":3337,"description":3338,"ogTitle":3337,"ogDescription":3338,"noIndex":6,"ogImage":3339,"ogUrl":3340,"ogSiteName":686,"ogType":687,"canonicalUrls":3340,"schema":3341},"Secure by Design principles meet DevSecOps innovation in GitLab 17","GitLab reinforced a commitment to Secure by Design principles across key aspects of the software development lifecycle in latest release, further protecting the software supply chain.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749676004/Blog/Hero%20Images/blog-image-template-1800x945__6_.png","https://about.gitlab.com/blog/secure-by-design-principles-meet-devsecops-innovation-in-gitlab-17","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Secure by Design principles meet DevSecOps innovation in GitLab 17\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Elisabeth Burrows\"}],\n        \"datePublished\": \"2024-06-05\",\n      }",{"title":3337,"description":3338,"authors":3343,"heroImage":3339,"date":3345,"body":3346,"category":694,"tags":3347},[3344],"Elisabeth Burrows","2024-06-05","Secure by Design just [turned one](https://about.gitlab.com/blog/happy-birthday-secure-by-design/)! Introduced by the Cybersecurity and Infrastructure Security Agency (CISA) a little over a year ago, Secure by Design principles serve as a directive for technology providers to embed security at the heart of their products from the outset of development. This approach is the clearest answer to address cyber attacks, dramatically reducing the number of exploitable flaws before they are introduced to the market for broad use or consumption. Cyberattacks can be more prevalent when businesses and vendors “bolt on” security as an afterthought, amplifying the need for Secure by Design solutions. With the launch of [GitLab 17](https://about.gitlab.com/releases/2024/05/16/gitlab-17-0-released/), we have strengthened our commitment to Secure by Design principles across five key aspects of the software development lifecycle. Although no supply chain is 100% immune to cyber threats, it is imperative to embrace a proactive security strategy to protect against persistent threats from malicious actors.\n\n> Discover the future of AI-driven software development with our GitLab 17 virtual launch event. [Watch today!](https://about.gitlab.com/seventeen/)\n\n## How GitLab 17 aligns with Secure by Design principles\n\n### 1. Enhance secure coding practices\n\nFostering secure software development practices is a key element to CISA’s Secure by Design framework. CISA recommends alignment to the [Secure Software Development Framework (SSDF)](https://csrc.nist.gov/pubs/sp/800/218/final) from the National Institute of Standards and Technology (NIST). GitLab’s robust [application security scanners](https://about.gitlab.com/blog/getting-started-with-gitlab-application-security/) demonstrate strong default alignment to this framework. In GitLab 17, we added streamlined Static Application Security Testing ([SAST](https://docs.gitlab.com/ee/user/application_security/sast/)) analyzer coverage for more languages, offering a simpler, more customizable scan experience. The recent [acquisition of Oxeye](https://about.gitlab.com/press/releases/2024-03-20-gitlab-acquires-oxeye-to-advance-application-security-and-governance-capabilities/) enhances SAST accuracy, reducing false positives and offering actionable insights to tackle application-layer risks proactively. Other related improvements in GitLab 17 include [API Security Testing analyzer](https://docs.gitlab.com/ee/user/application_security/api_security_testing/) updates, [advanced vulnerability tracking for Secret Detection](https://docs.gitlab.com/ee/user/application_security/secret_detection/pipeline/#advanced-vulnerability-tracking), and [Dependency Scanning support for Android](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/index.html#enabling-dependency-scanning-by-using-cicd-components). GitLab also continues to improve its [dynamic software bill of materials (SBOM) management](https://about.gitlab.com/blog/the-ultimate-guide-to-sboms/) capabilities.\n\n### 2. Manage vulnerabilities at scale\n\nMalicious actors capitalize on cost-effective tactics, leveraging basic vulnerabilities to cause widespread disruption. GitLab’s [Vulnerability Report](https://docs.gitlab.com/ee/user/application_security/vulnerability_report/) enables you to quantify risk across your portfolio in a single view, identifying key vulnerability details throughout your supply chain. \nImprovements to [Vulnerability Report filtering](https://docs.gitlab.com/ee/user/application_security/vulnerability_report/#vulnerability-report-filters) in GitLab 17 increased usability of the report at scale. Actionable security findings are vital for developers to address critical weaknesses. GitLab provides [vulnerability insights](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/), [security training for vulnerabilities](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/#view-security-training-for-a-vulnerability), and [vulnerability explanation](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/#vulnerability-explanation). \n\n### 3. Transition to memory-safe languages with AI\n\nIn a recent [virtual panel with the Atlantic Council](https://www.atlanticcouncil.org/event/the-secure-by-design-imperative/), CISA Senior Technical Advisor Jack Cable stated, “Technology manufacturers must focus on eliminating entire classes of vulnerability, rather than playing “whack-a-mole” with their defects.” In CISA’s [Secure by Design whitepaper](https://www.cisa.gov/sites/default/files/2023-10/SecureByDesign_1025_508c.pdf), they recommend that manufacturers take steps to eliminate one of the largest classes of vulnerabilities by migrating existing products and building new products using memory-safe languages. A memory-safe language is a language where memory allocation and garbage collection are abstracted away from the developer and handled by the programming language itself. Such languages include Python, Java, and Go, to name a few. Vulnerabilities related to memory safety are the most common and dangerous. Technology manufacturers can effectively address vulnerabilities by integrating memory-safe language development practices. [GitLab Duo](https://about.gitlab.com/gitlab-duo/), our suite of AI-powered features, provides AI-accelerated assistance for memory-safe code conversions:\n\n- Accelerate application development: [GitLab Duo Code Explanation](https://docs.gitlab.com/ee/user/ai_features.html#code-explanation-in-the-ide) succinctly articulates code functionality in everyday language, helping developers understand code quickly and add value faster. [GitLab Duo Code Suggestions](https://docs.gitlab.com/ee/user/ai_features.html#code-suggestions) assists developers in writing secure code efficiently and speeding up cycle times by handling repetitive coding tasks effectively.\n- Convert to memory-safe code: [GitLab Duo Chat](https://docs.gitlab.com/ee/user/gitlab_duo_chat_examples.html#refactor-code-in-the-ide) can help expedite memory-safe language refactoring by suggesting changes based on coding patterns, libraries, functions, algorithms, programming languages, performance, or vulnerabilities.\n- Secure AI-generated code: [GitLab Duo Vulnerability Explanation](https://docs.gitlab.com/ee/user/ai_features.html#vulnerability-explanation) provides clear insights into identified security issues, while [GitLab Duo Vulnerability Resolution](https://docs.gitlab.com/ee/user/ai_features.html#vulnerability-resolution) can automatically generate a merge request to mitigate a vulnerability. \n\nIn GitLab 17, we also have added the means to validate and track AI impact to your development progress through [AI Impact Analytics](https://about.gitlab.com/blog/developing-gitlab-duo-ai-impact-analytics-dashboard-measures-the-roi-of-ai/).\n\n### 4. Align to the principle of least privilege\n\nAligning product deployment guides with zero trust architecture, such as the [CISA Zero Trust Maturity Model](https://www.cisa.gov/sites/default/files/2023-04/zero_trust_maturity_model_v2_508.pdf), is a key recommendation in Secure by Design. In zero trust security, the [principle of least privilege (PoLP)](https://about.gitlab.com/blog/the-ultimate-guide-to-least-privilege-access-with-gitlab/0) is a key element within the overarching framework. The PoLP is a concept in which a user's access rights should be limited to the bare minimum needed for them to complete the tasks required within their respective roles. By keeping a tight rein on user access rights, granting only the necessary permissions for their tasks, organizations uphold the core tenet of [zero trust](https://about.gitlab.com/blog/why-devops-and-zero-trust-go-together/). Maintaining a clear separation of duties is the first step in upholding this principle. GitLab's [policy management](https://docs.gitlab.com/ee/administration/compliance.html#policy-management) features empower security and compliance teams to oversee operations while defining responsibilities among security, compliance, legal, and engineering units. By implementing GitLab's [security policies](https://docs.gitlab.com/ee/user/application_security/policies/), development teams gain process flexibility, ensuring the delivery of stable, reliable, and high-quality code. With the ability to establish rules and policies tailored to the organization's unique needs, teams can utilize granular user roles, permissions, and customizable compliance settings for specific projects, groups, and individuals. GitLab 17 introduces enhanced governance controls via [permissions customizations](https://about.gitlab.com/releases/2024/05/16/gitlab-17-0-released/#new-permissions-for-custom-roles), reducing unnecessary privilege escalation.\n\n## How we are committed to Secure by Design principles\n\nOne of the principles of Secure by Design business practices is the notion of leading from the top. It's imperative for organizations to secure executive buy-in that places Secure by Design at the forefront of business priorities, nurturing an environment where security takes precedence. GitLab recently joined the ranks of technology leaders who signed CISA’s [Secure by Design Pledge](https://www.cisa.gov/securebydesign/pledge/statements-of-support#JoshLemosCISOGitLab), showcasing our commitment to uphold CISA’s Secure by Design goals. This public commitment, paired with strategic investments, a culture of transparency, and product designs that prioritize security, fosters a robust security ethos that directly benefits end users. With the launch of GitLab 17, GitLab propels security and compliance solutions forward, harnessing AI advancements to empower clients to embrace a Secure by Design methodology with confidence.\n\n> Get familiar with GitLab's secure-by-design platform today with a [free trial of GitLab Ultimate](https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/blog&glm_content=default-saas-trial). \n",[186,694,496,9],{"slug":3349,"featured":91,"template":698},"secure-by-design-principles-meet-devsecops-innovation-in-gitlab-17","content:en-us:blog:secure-by-design-principles-meet-devsecops-innovation-in-gitlab-17.yml","Secure By Design Principles Meet Devsecops Innovation In Gitlab 17","en-us/blog/secure-by-design-principles-meet-devsecops-innovation-in-gitlab-17.yml","en-us/blog/secure-by-design-principles-meet-devsecops-innovation-in-gitlab-17",{"_path":3355,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3356,"content":3361,"config":3367,"_id":3369,"_type":14,"title":3370,"_source":16,"_file":3371,"_stem":3372,"_extension":19},"/en-us/blog/secure-compliant-and-ai-powered-get-to-know-3-new-gitlab-features",{"title":3357,"description":3358,"ogTitle":3357,"ogDescription":3358,"noIndex":6,"ogImage":2032,"ogUrl":3359,"ogSiteName":686,"ogType":687,"canonicalUrls":3359,"schema":3360},"Secure, compliant, and AI-powered: Get to know 3 new GitLab features","Enhance security, leverage new AI capabilities, and protect sensitive data with our latest platform improvements.","https://about.gitlab.com/blog/secure-compliant-and-ai-powered-get-to-know-3-new-gitlab-features","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Secure, compliant, and AI-powered: Get to know 3 new GitLab features\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Jessica Hurwitz\"}],\n        \"datePublished\": \"2025-01-27\",\n      }",{"title":3357,"description":3358,"authors":3362,"heroImage":2032,"date":3364,"body":3365,"category":848,"tags":3366},[3363],"Jessica Hurwitz","2025-01-27","AI capabilities are rapidly reshaping how teams build, secure, and deploy applications. As part of our ongoing commitment to helping you navigate the evolving marketplace, GitLab has introduced more than 440 improvements in the past three releases. We're excited to spotlight three standout features making an immediate impact on how teams approach AI-powered DevSecOps. In addition, we announced we are partnering with AWS to launch [GitLab Duo with Amazon Q](https://about.gitlab.com/blog/gitlab-duo-with-amazon-q-devsecops-meets-agentic-ai/), combining our strengths to transform software development. We're creating an experience, together, that makes AI-powered development feel seamless and upholds the security, compliance, and reliability that enterprises require.\n\n> Learn how GitLab can [deliver 483% ROI over the next three years](https://about.gitlab.com/blog/gitlab-ultimates-total-economic-impact-483-roi-over-3-years/), according to Forrester Consulting.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://player.vimeo.com/video/1056012314?badge=0\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media\" title=\"GitLab 17.6-17.8 Quarterly Release Overview\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## 1. Vulnerability Resolution: Streamline security remediation\n\nGitLab’s 2024 [Global DevSecOps Report](https://about.gitlab.com/developer-survey/) found that 66% of companies are releasing software twice as fast — or faster — than in previous years, as businesses strive to deliver more value to their customers than competitors. However, speed introduces risk. With security teams [outnumbered by dev teams 80:1](https://www.opentext.com/assets/documents/en-US/pdf/developer-driven-appsec-security-at-the-speed-of-devops-pp-en.pdf), threat actors are able to exploit applications at a record pace. Last year alone, [80% of the top data breaches](https://www.crowdstrike.com/2024-state-of-application-security-report/) stemmed from attacks at the application layer.\n\n[GitLab Duo Vulnerability Resolution](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/#vulnerability-resolution) addresses this challenge head-on. When vulnerabilities are detected in your code, you can now access detailed information right from the vulnerability report and invoke GitLab Duo to automatically create a merge request that updates your code and mitigates the risk. While developers must review these auto-generated merge requests before merging to verify the changes, this automation significantly streamlines the remediation process. Vulnerability Resolution pairs with [Vulnerability Explanation](https://about.gitlab.com/the-source/ai/understand-and-resolve-vulnerabilities-with-ai-powered-gitlab-duo/), which also recently became generally available. Vulnerability Explanation gives developers a detailed description of the vulnerability infecting their code, real-world examples of how attackers can exploit the vulnerable code, and practical suggestions for remediation.\n\nBy expediting the vulnerability remediation process, your teams can focus on delivering software faster while maintaining strong security practices. With less time spent researching and remediating vulnerabilities, developers can concentrate on building features that drive business value.\n\n_GitLab Duo Vulnerability Resolution is available as a [GitLab Duo Enterprise add-on](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/?type=free-trial&toggle=gitlab-duo-pro)._\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"\nhttps://www.youtube.com/embed/VJmsw_C125E?si=W7n1ESS63xkPyH4H\" frameborder=\"0\" title=\"GitLab Vulnerability Resolution\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## 2. Model Registry: Breaking down silos between Data Science and Development teams\n\nFor organizations building AI-powered applications, bridging the gap between data science and software development teams has been a persistent challenge. Data scientists and developers often work in disconnected tools and workflows, leading to friction, delays, and potential errors when deploying models to production.\n\n[GitLab Model Registry](https://docs.gitlab.com/ee/user/project/ml/model_registry/) directly addresses this challenge by providing a centralized hub where data science and development teams can collaborate seamlessly within their existing GitLab workflow. Built with [MLflow](https://docs.gitlab.com/ee/user/project/ml/experiment_tracking/mlflow_client.html#model-registry) native integration, the registry allows data scientists to continue using their preferred tools while making models and artifacts instantly accessible to the broader development team.\nThis unified approach transforms team collaboration. Data scientists can version models, store artifacts, and document model behavior through comprehensive model cards, while developers can easily integrate these models into their applications using GitLab CI/CD pipelines for automated testing and deployment.\n\nAdditionally, the Model Registry's semantic versioning and GitLab API integration enables teams to implement robust governance and automate production deployments, creating a streamlined environment where data scientists and developers can work together effectively to deliver AI-powered innovation.\n\n_Model Registry is available across all tiers for SaaS and self-managed customers. See the [release blog for 17.6](https://about.gitlab.com/releases/2024/11/21/gitlab-17-6-released/#model-registry-now-generally-available) and [documentation](https://docs.gitlab.com/ee/user/project/ml/model_registry/) for more._\n\n## 3. Secret Push Protection: Shift security left with proactive secret detection\n\nTeams often face a critical security challenge: Developers may hardcode sensitive information like API keys, tokens, and credentials as plain text in source code repositories, sometimes without even realizing it. This creates an easy target for threat actors and puts your organization at risk.\n\n[Secret Push Protection](https://about.gitlab.com/blog/prevent-secret-leaks-in-source-code-with-gitlab-secret-push-protection/) directly addresses this problem by blocking developers from pushing code that contains secrets, significantly reducing the likelihood of a breach. It works by leveraging customizable rules to identify high-confidence secrets before they ever reach your repository.\n\nWhat makes this solution particularly powerful is its integration with our pipeline secret detection, creating a comprehensive defense strategy.\n\n_Secret Push Protection is now generally available for all [GitLab Ultimate tier](https://about.gitlab.com/pricing/ultimate/) and [GitLab Dedicated](https://about.gitlab.com/dedicated/) customers._\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"\nhttps://www.youtube.com/embed/SFVuKx3hwNI?si=aV_3Lazs2AiDH3Jf\" title=\"Introduction to Secret Push Protection\" frameborder=\"0\" title=\"GitLab Vulnerability Resolution\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Put these features to work today\n\nAt GitLab, we’re committed to making it easier for teams to build software, faster. Capabilities like GitLab Duo Vulnerability Resolution, Model Registry, and Secret Push Protection are just a few of the recent innovations we’ve delivered to help developers and security teams level up their DevSecOps workflows. To learn more, check out our [releases page](https://about.gitlab.com/releases/categories/releases/).\n\n> Get started with these new features today with [a free trial of GitLab Ultimate](https://about.gitlab.com/free-trial/).\n",[9,496,719,848,694],{"slug":3368,"featured":91,"template":698},"secure-compliant-and-ai-powered-get-to-know-3-new-gitlab-features","content:en-us:blog:secure-compliant-and-ai-powered-get-to-know-3-new-gitlab-features.yml","Secure Compliant And Ai Powered Get To Know 3 New Gitlab Features","en-us/blog/secure-compliant-and-ai-powered-get-to-know-3-new-gitlab-features.yml","en-us/blog/secure-compliant-and-ai-powered-get-to-know-3-new-gitlab-features",{"_path":3374,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3375,"content":3381,"config":3385,"_id":3387,"_type":14,"title":3388,"_source":16,"_file":3389,"_stem":3390,"_extension":19},"/en-us/blog/secureflag-integrated-with-gitlab-for-rapid-vulnerability-remediation",{"title":3376,"description":3377,"ogTitle":3376,"ogDescription":3377,"noIndex":6,"ogImage":3378,"ogUrl":3379,"ogSiteName":686,"ogType":687,"canonicalUrls":3379,"schema":3380},"SecureFlag integrated with GitLab for rapid vulnerability remediation","Empower developers with hands-on security training within the DevSecOps platform.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679321/Blog/Hero%20Images/cover_image_secureflag.png","https://about.gitlab.com/blog/secureflag-integrated-with-gitlab-for-rapid-vulnerability-remediation","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"SecureFlag integrated with GitLab for rapid vulnerability remediation\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Alana Bellucci\"}],\n        \"datePublished\": \"2023-06-29\",\n      }",{"title":3376,"description":3377,"authors":3382,"heroImage":3378,"date":2253,"body":3383,"category":694,"tags":3384},[1573],"\n\nAs part of our commitment to developer-led security, GitLab has integrated SecureFlag's vulnerability remediation training for developers into the DevSecOps platform. [SecureFlag’s training](https://www.secureflag.com/solutions?utm_source=blog&utm_medium=organic&utm_campaign=GitLab+blog) is unique as it offers labs where developers can learn to remediate vulnerabilities in a live environment. \n\nOften, organizations attempt to address vulnerabilities by referring to incomplete or misleading advice. This not only hinders the remediation process, but might lead to additional insecure applications and increased risk. With the SecureFlag integration with GitLab, organizations can continue to shift security left in the software development lifecycle, gaining more insight, oversight, and control of their assets, processes, and overall security posture. Real-time access to vulnerability information ensures consistent, up-to-date, and trustworthy guidance and documentation for tackling the remediation of security findings.\n\nWhen developers receive GitLab vulnerability scan results on the DevSecOps platform, SecureFlag provides a clear understanding of the identified vulnerabilities, indicates the best way to remediate them, and presents hands-on labs for practice.\n\n## How the SecureFlag-GitLab integration works\nGitLab's security scanners detect vulnerabilities when merging to a default branch. These vulnerabilities surface in the merge request and pipeline or in the Vulnerability Report. Once a vulnerability is identified, SecureFlag integration steps in to streamline the vulnerability remediation process. Using the information provided in the vulnerability details, SecureFlag generates a link to a training resource for the developer, which provides guidance throughout the remediation of that specific security problem.\n\n![Developer Workflow](https://about.gitlab.com/images/blogimages/2023-06-15-empowering-developers-via-GitLab-integrating-SecureFlag-for-rapid-vulnerability-remediation/developer-workflow.png){: .shadow}\n\n\nBy clicking on the link, developers are led to a knowledge base article that illustrates, with code examples, how to address a vulnerability in the specific programming language. Moreover, they can start a hands-on lab in a few seconds and practice their remediation skills before diving into the actual work. This level of preparedness has enabled organizations to significantly decrease the number of security retests, as developers now know exactly what to do and are often able to fix the issue on their first attempt.\n\n![SecureFlag SQL Injection Page](https://about.gitlab.com/images/blogimages/2023-06-15-empowering-developers-via-GitLab-integrating-SecureFlag-for-rapid-vulnerability-remediation/secureflag-knowledge-base.png){: .shadow}\n\n\n## SecureFlag's hands-on labs\nSecureFlag’s hands-on labs stand out as a powerful learning tool for developers. Labs comprise a complete virtualized desktop computer with a real development environment unique to the programming language in question. Labs are spun up in seconds and are designed to facilitate effective and engaging training experiences with the goal of maximizing retention.\n\n![SecureFlag Lab](https://about.gitlab.com/images/blogimages/2023-06-15-empowering-developers-via-GitLab-integrating-SecureFlag-for-rapid-vulnerability-remediation/secureflag-lab.gif){: .shadow}\n\n\nSecureFlag labs feature:\n- support for over 45+ technologies\n- multiple difficulty levels and scenarios for each vulnerability\n- gamified learning with points, trophies, and certifications\n- adaptive training based on previous results\n\n## How to install and configure SecureFlag training on GitLab\nSecureFlag training is available to all GitLab Ultimate customers and can be enabled for any project. Additional details can be found [here](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/#enable-security-training-for-vulnerabilities).\n![Security Training Settings](https://about.gitlab.com/images/blogimages/2023-06-15-empowering-developers-via-GitLab-integrating-SecureFlag-for-rapid-vulnerability-remediation/security-training-settings.png){: .shadow}\n\n\nOnce installed, you can view the results from a GitLab security scan (including GitLab’s integration partners) in a merge request, the pipeline security tab, or a vulnerability details page. When you open a vulnerability record, you will see a direct link to the training. GitLab then pulls a training module from SecureFlag that best matches the specific security issue and the appropriate language or framework in which it was detected.\n\nThe integration of SecureFlag within GitLab enhances the robustness of an organization's security strategy by enabling a proactive, developer-led security approach. The training material and hands-on labs ensure that developers are well-equipped to handle any identified vulnerabilities, thus reducing remediation time and increasing your overall project security.\n",[694,9,848,719],{"slug":3386,"featured":6,"template":698},"secureflag-integrated-with-gitlab-for-rapid-vulnerability-remediation","content:en-us:blog:secureflag-integrated-with-gitlab-for-rapid-vulnerability-remediation.yml","Secureflag Integrated With Gitlab For Rapid Vulnerability Remediation","en-us/blog/secureflag-integrated-with-gitlab-for-rapid-vulnerability-remediation.yml","en-us/blog/secureflag-integrated-with-gitlab-for-rapid-vulnerability-remediation",{"_path":3392,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3393,"content":3398,"config":3404,"_id":3406,"_type":14,"title":3407,"_source":16,"_file":3408,"_stem":3409,"_extension":19},"/en-us/blog/self-managed-support-for-code-suggestions",{"title":3394,"description":3395,"ogTitle":3394,"ogDescription":3395,"noIndex":6,"ogImage":839,"ogUrl":3396,"ogSiteName":686,"ogType":687,"canonicalUrls":3396,"schema":3397},"Self-managed support for Code Suggestions (Beta)","Self-managed support for Code Suggestions (Beta) is coming in GitLab 16.1.","https://about.gitlab.com/blog/self-managed-support-for-code-suggestions","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Self-managed support for Code Suggestions (Beta)\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Roger Woo\"}],\n        \"datePublished\": \"2023-06-15\",\n      }",{"title":3394,"description":3395,"authors":3399,"heroImage":839,"date":3401,"body":3402,"category":781,"tags":3403},[3400],"Roger Woo","2023-06-15","\n\n\u003Ci>This blog post is part of an ongoing series about GitLab's journey to [build and integrate AI/ML into our DevSecOps platform](/blog/ai-ml-in-devsecops-series/). The series starts here: [What the ML is up with DevSecOps and AI?](/blog/what-the-ml-ai/). Throughout the series, we'll feature blogs from our product, engineering, and UX teams to showcase how we're infusing AI/ML into GitLab.\u003C/i>\n\nGitLab [Code Suggestions (Beta)](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html) uses generative AI to suggest code while you’re developing. Since introduction in GitLab SaaS with 15.9, we've heard self-managed customers have wanted to use the feature. We're now bringing Code Suggestions to self-managed instances beginning with GitLab 16.1 (expected to be released June 22). Self-managed users working with VS Code or GitLab’s WebIDE can now receive code suggestions to help accelerate your development efforts while you type.\n\n## How does Code Suggestions work?\nA self-managed instance administrator must enable Code Suggestions on behalf of an organization's entire instance. Once enabled, users of that self-managed instance can authenticate their IDE to GitLab.com infrastructure using a secure handshake with the user's self-managed instance. As users type in their IDE, a context window containing relevant source code is securely transmitted to GitLab’s infrastructure, which will return an AI-generated code suggestion. GitLab does not have any visibility into a self-managed customer’s code other than what is sent to generate the Code Suggestion. GitLab does not persist any customer code sent in that context window nor train on customer data.\n\nIn this video, Senior Backend Engineer [Nikola Milojevic](https://gitlab.com/nmilojevic1) demonstrates how to set up and configure GitLab’s Code Suggestions for self-managed users on VS Code.\n\n\u003Ciframe width=\"560\" height=\"315\" src=\"https://www.youtube-nocookie.com/embed/-A4amG3E49Y\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen>\u003C/iframe>\n\n## How Code Suggestions uses data\nGitLab is mindful of privacy when we design our AI-powered features. With Code Suggestions, we securely transmit the data needed to generate a code suggestion, and we process all personal data in accordance with our [privacy statement](https://about.gitlab.com/privacy/). Our VS Code Workflow extension will securely transmit a minimal amount of data required to generate a code suggestion. GitLab does not receive any information outside of an IDE’s context. Read more about [Code Suggestions data usage](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#data-privacy).\n\n## Try Code Suggestions\nWe will be provisioning access on a customer-by-customer basis for this initial iteration of GitLab Code Suggestions (Beta) on self-managed instances. Please leave a note in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/415393) tagging your Customer Success Manager for help with enabling Code Suggestions once your instance is ready.\n\nCode Suggestions for self-managed instances will require GitLab 16.1. Customers may try Code Suggestions either via GitLab’s WebIDE or VS Code’s GitLab Workflow Extension (version [3.67+](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow&ssr=false#version-history)).\n\n## Iterating on AI/ML features\nThis is just the start of the ways we're infusing GitLab with AI/ML capabilities to help GitLab users become more efficient and effective at their jobs. We are [looking across the software development lifecycle](/blog/what-the-ml-ai/) for painful and time-consuming tasks that are ideal for AI-assisted features. We'll continue to share these demos throughout this blog series.\n\nInterested in using these AI-generated features? [Join our waitlist](https://forms.gle/9eeUkPJauKsbLaoz5) and share your ideas.\n\nContinue reading our \"[AI/ML in DevSecOps](https://about.gitlab.com/blog/ai-ml-in-devsecops-series/)\" series.\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[9,848,719,717],{"slug":3405,"featured":6,"template":698},"self-managed-support-for-code-suggestions","content:en-us:blog:self-managed-support-for-code-suggestions.yml","Self Managed Support For Code Suggestions","en-us/blog/self-managed-support-for-code-suggestions.yml","en-us/blog/self-managed-support-for-code-suggestions",{"_path":3411,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3412,"content":3418,"config":3422,"_id":3424,"_type":14,"title":3425,"_source":16,"_file":3426,"_stem":3427,"_extension":19},"/en-us/blog/six-reasons-cisco-learning-and-certifications-adopted-gitlab",{"title":3413,"description":3414,"ogTitle":3413,"ogDescription":3414,"noIndex":6,"ogImage":3415,"ogUrl":3416,"ogSiteName":686,"ogType":687,"canonicalUrls":3416,"schema":3417},"6 reasons Cisco Learning and Certifications adopted GitLab","Learn what Cisco Learning and Certifications's principal engineer and lead architect shared about the organization's use of GitLab at our DevSecOps World Tour in Chicago.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749670302/Blog/Hero%20Images/lightbulb-book.png","https://about.gitlab.com/blog/six-reasons-cisco-learning-and-certifications-adopted-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"6 reasons Cisco Learning and Certifications adopted GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sharon Gaudin\"}],\n        \"datePublished\": \"2023-09-05\",\n      }",{"title":3413,"description":3414,"authors":3419,"heroImage":3415,"date":1652,"body":3420,"category":972,"tags":3421},[756],"\nAfter adopting the GitLab DevSecOps Platform, the learning and certification arm of tech giant Cisco Systems, Inc. saw its toolchain shrink and was able to offer its entire software development team a way to improve collaboration and accelerate production.\n\nThat’s part of the story that Hank Preston, principal engineer and lead architect with [Cisco Learning and Certifications](https://www.cisco.com/c/en/us/training-events/training-certifications.html), shared in an on-stage interview at the Chicago stop of [GitLab’s DevSecOps World Tour](https://about.gitlab.com/events/devsecops-world-tour/).\n\nPreston also spent part of his conversation with Nico Ochoa, senior major account executive at GitLab, talking about the rapid rise in interest in AI and how that is likely to affect everything from how they create software to how newer developers learn to code.\n\nHere are some of the opportunities Cisco Learning and Certifications is gaining from using GitLab:  \n \n## 1. Getting a handle on version control\nPreston said one of the biggest challenges he was looking to overcome by adopting a DevSecOps platform was resolving and [preventing conflicts](/topics/version-control/how-implement-version-control/) they had keeping track of code modifications and version updates, which can be easy to lose sight of when handling them manually. For example, the team had been storing templates and configuration pieces in different places and ended up having an “extreme inability” to know what had been changed and where it went, he said. Using a platform gives the team a way to more easily and clearly manage source and version controls. “It gave us a way to actually keep everything in one place, and understand the trajectory and history of changes,” he said.\n\n## 2. Ensuring accountability\n“Gaining accountability was a big one for us,” Preston told the audience. “We needed to know when something changed, who changed it, and who approved that change.” In an efficient, high-performing DevSecOps team, this kind of transparent accountability is critical. Both the development and operations teams have an equal stake in DevSecOps success. The problem is that it can be difficult to do when team structures and responsibilities are outdated or haven’t been updated in documentation. Clearly distributing functions and noting who needs to do a task, as well as when and who accomplished a task, makes this work. “When I taught a bunch of network engineers how to do merge requests and branching, it became less of a challenge for us,” Preston said. \n\n## 3. Consolidating their toolchain\n“[Reducing our toolchain](/blog/too-many-toolchains-a-devops-platform-migration-is-the-answer/) … that was one of the reasons we selected GitLab. I didn't want to have to have a source control tool and a CI tool and an issues tool,” Preston said.\n\nCisco Learning and Certifications still uses Jira — a decision Preston said was not his own. “I'm looking forward to potentially getting rid of [Jira] in the future. But not having to manage a bunch of tools was a big value for us because then there are less things to integrate, less things to upgrade, and less things I have to train people on how to use,” he added.\n\n## 4. Boosting collaboration \nWhen different team members want to [collaborate](/blog/5-ways-collaboration-boosts-productivity-and-your-career/) on a project, sharing responsibilities and information, it’s critical for them to be able to all work in the same place. Preston explained that having a single, end-to-end platform that everyone works in means teammates don’t have to go looking for something across multiple tools. “Now everybody knows where to go to find the code and the templates they need. And the automation pieces are right there,” he added. “We don’t need to go looking for things or logging into, say, Mark's particular OneDrive folder to find a piece we need.” \n\n## 5. Having a single source of truth\n“I'm a big proponent of the concept of a single source of truth,” said Preston. “I tell people that the network shouldn't be the source of truth. That's the implementation of what our source of truth is.”\n\nCisco Learning and Certifications uses GitLab as the source of truth for a lot of its configuration templates, automation scripts and jobs, and infrastructure as code, according to Preston. “So whether it’s our data centers or sites, all the data should be aggregated and stored according to a single reference point. We have a plan and a way of doing things and everyone can see what that is,” he said.\n\n## 6. Speeding up production\nPreston also noted he’s using the platform to gain insight into and improve the time it takes to move a software project from ideation to development and into deployment. “One of the metrics I'm trying to use with our team now is how long it takes us to get something from an idea to working software,” he said. “If I’m trying to get an update into production or if I'm trying to fix something on the infrastructure stack, how long does it take us to get to where we feel comfortable pushing it into production? That's a metric we're watching. I don't want it to take 18 months to go from an idea to release. I needed that to be much faster.”\n\n## How AI could affect software creation, developer learning\nDuring his on-stage talk, Preston also turned his attention to artificial intelligence (AI), speaking about the growing call for the use of [AI in DevSecOps](/blog/ai-assisted-code-suggestions/), how it may be regulated, and how it could affect software developers.\n\n“AI in DevOps has changed dramatically just over the last three months or so,” he said. “The [AI transition](/blog/extending-code-suggestions/) has been rapid. I can't even pretend to guess what the next two years of it will look like, let alone the next five years. I think it’s an interesting challenge, and, well, to be honest, it makes me personally nervous.”\n\nHe added that he’s concerned about the issue of intellectual property and who owns the code that AI generates. Will the software built by AI be owned by the company the code was built for, or by the person or company that created the AI?\n\n“The intellectual property question is a big one. It’s something that has to be figured out,” he said.\n\nAnother thing that nags at Preston is how using AI in DevSecOps will affect the way people learn to develop code if it’s automatically being generated for them. Will people still become coding wizards if they don’t actually have to do it themselves?\n\n“I think about how this will affect the path of software developers and engineers who are coming onto the team,” he said. “How will they become our coding experts in the future? I love the code generation process but it also makes me worried. I wonder — and part of me thinks I'm just being the grouchy old man — how do we teach the new engineers how to make a connection to MySQL if the minute they type ‘M-Y-S-Q-L,’ the code comes up? That’s a scary spot. I know there's a lot of value to the grunt work being thinned out, but there’s value that comes with the doing and learning.”\n\nAnswering a question about whether Cisco allows developers to use AI-generated code, Preston replied, “Generally, no.” He said executives need to work through intellectual property questions first, but AI is a tool they plan to implement.\n\nPreston also was asked about maintaining standards when using AI to generate code. “We're looking for AI solutions we can leverage that will meet the coding requirements we have across the board,” he said. “But I think the question on standards is important. It's going to be the same way we handle it when people write code. Code will all have to be checked against set standards, whether it’s written by people or AI.”\n\n_Preston’s team within Cisco Learning and Certifications is responsible for creating and maintaining the software needed for the digital learning platform that offers instant user access to training information, classes, course materials, and exam preparation resources. Cisco employees use the platform to gain certifications, like CCNA, CCMP, and CCIE._\n\n_GitLab’s DevSecOps World Tour was designed to enable everyone — from technology champions to executives and software development team members — to gather and learn about the ideas and technologies driving the DevSecOps transformation. Learn more about our [DevSecOps World Tour](https://about.gitlab.com/events/devsecops-world-tour/)._\n",[9,974,717],{"slug":3423,"featured":6,"template":698},"six-reasons-cisco-learning-and-certifications-adopted-gitlab","content:en-us:blog:six-reasons-cisco-learning-and-certifications-adopted-gitlab.yml","Six Reasons Cisco Learning And Certifications Adopted Gitlab","en-us/blog/six-reasons-cisco-learning-and-certifications-adopted-gitlab.yml","en-us/blog/six-reasons-cisco-learning-and-certifications-adopted-gitlab",{"_path":3429,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3430,"content":3436,"config":3442,"_id":3444,"_type":14,"title":3445,"_source":16,"_file":3446,"_stem":3447,"_extension":19},"/en-us/blog/speed-security-devops",{"title":3431,"description":3432,"ogTitle":3431,"ogDescription":3432,"noIndex":6,"ogImage":3433,"ogUrl":3434,"ogSiteName":686,"ogType":687,"canonicalUrls":3434,"schema":3435},"How to ensure security at the speed of DevOps","Read here on how to speed up your secure DevOps for faster delivery on your safe and secure applications.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749678356/Blog/Hero%20Images/balance-speed-security-devops.jpg","https://about.gitlab.com/blog/speed-security-devops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to ensure security at the speed of DevOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Vanessa Wegner\"}],\n        \"datePublished\": \"2019-10-31\",\n      }",{"title":3431,"description":3432,"authors":3437,"heroImage":3433,"date":3439,"body":3440,"category":950,"tags":3441},[3438],"Vanessa Wegner","2019-10-31","\nChoosing between speed and security leaves some development teams walking a fine\nline between order and chaos. Even in [DevOps](/topics/devops/), if your security practices are\nstill largely manual, teams often choose to release apps before they’re fully\nsecured, rather than waiting for the security team to address critical\nvulnerabilities.\n\nBut what if I told you that you don’t need to choose? Pull your security team,\ntests and practices to the beginning of the SDLC, and embed them throughout to\nreduce time to launch – and launch a secure product.\n\n## Six ways to bring security up to speed\n\n### 1. Make small, frequent changes\nProduce code in small chunks or units, and then run automated tests on those\nunits as they’re committed, so the developers can remediate any\nvulnerabilities on the spot – rather than waiting for feedback days, weeks, or\neven months later. Running regular tests saves time down the road, when the completed\napp is tested before launch.\n\n### 2. Educate developers _and_ security teams\nAdopt or create an educational program that teaches developers to recognize\ncommon vulnerabilities and remediate on their own. Security professionals should\nalso be educated on application development and emerging technology,\nso they can understand developers’ work and ensure their organization isn’t\noverlooking any major vulnerabilities.\n\n### 3. Fail fast, fix fast\nFailing fast is a critical component of the DevOps mindset – and should be\napplied to developers’ security practices as well. If the automated scans\nreveal vulnerabilities, developers should be encouraged to take\nremediation into their own hands, both as a form of self-education, and to keep\nthe SDLC moving quickly.\n\n### 4. Prioritize risks\nRisks will take different levels of priority within a single app, or across all\nof an organization’s apps. DevOps and security teams should work together to\nestablish security guidelines that allow teams to prioritize which risks to\naddress immediately, and which may not need remediation in the short term.\n[Joe Coletta of IBM brings up an important distinction](https://securityintelligence.com/how-to-balance-speed-and-security-in-your-application-security-program/):\nFlaws should be assessed not only by level of severity, but also by likelihood\nof exploitation by an attacker.\n\n### 5. Automate as much as possible\nManual security processes cannot keep up – point blank. There are too many new\ntechnologies, deployments, and access requests for security teams to manually\nhandle everything. Tests should be pre-written and policies pre-defined so\nthat they’re addressed automatically within the development pipeline. Automation\nalso allows developers to focus on business demands – getting the app out\nquickly – while reducing the chance for human error.\n\n### 6. More is better\nTesting more frequently is always better, if it can be done efficiently. In rapid\ndevelopment, teams push small changes continuously, which also means they’re\nable to find vulnerabilities more easily, and push small fixes continuously.\n[As Forrester Research Director Amy DeMartine has stated](https://techbeacon.com/app-dev-testing/has-continuous-security-arrived-rise-rapid-development),\nany changes that developers make [using these methods] will only affect their\nsmall piece of code, without any ramifications on the rest. Ultimately, this\nincreases quality.\n\n## Like always, communication is key\n\nAbove all, your security and DevOps teams **must** be on the same page: A cross-team\nsecurity mindset requires a strong commitment to communication and transparency. Leaders should encourage\nmembers of both teams take initiative to understand the other team’s goals and\nintent, and why these goals are important to both the business and customer. Teams at\nevery business should focus on building a security-first mindset, as today’s\nexpanding attack surfaces provide opportunity for exploitation at every level.\nLastly, make it easy (or as easy as it can be). Integrated tools, or a single\ntool for the entire lifecycle (such as GitLab) will bring transparency to all\nsides of the operation and allow for seamless interactions, change logging,\nand efficiency.\n\nCover image by [Christian Englmeier](https://unsplash.com/@christianem) on [Unsplash](https://unsplash.com/photos/J7EUjSlNQtg)\n{: .note}\n",[694,1299,9],{"slug":3443,"featured":6,"template":698},"speed-security-devops","content:en-us:blog:speed-security-devops.yml","Speed Security Devops","en-us/blog/speed-security-devops.yml","en-us/blog/speed-security-devops",{"_path":3449,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3450,"content":3455,"config":3460,"_id":3462,"_type":14,"title":3463,"_source":16,"_file":3464,"_stem":3465,"_extension":19},"/en-us/blog/streamline-devsecops-engineering-workflows-with-gitlab-duo",{"title":3451,"description":3452,"ogTitle":3451,"ogDescription":3452,"noIndex":6,"ogImage":2899,"ogUrl":3453,"ogSiteName":686,"ogType":687,"canonicalUrls":3453,"schema":3454},"Streamline DevSecOps engineering workflows with GitLab Duo","Learn all the ways GitLab Duo's AI capabilities can improve the efficiency of development workflows. Includes in-depth tutorials and demos.","https://about.gitlab.com/blog/streamline-devsecops-engineering-workflows-with-gitlab-duo","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Streamline DevSecOps engineering workflows with GitLab Duo\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Abubakar Siddiq Ango\"}],\n        \"datePublished\": \"2024-12-05\",\n      }",{"title":3451,"description":3452,"authors":3456,"heroImage":2899,"date":3457,"body":3458,"category":781,"tags":3459},[1455],"2024-12-05","It's 9 a.m. somewhere, and a DevOps engineer is starting their day. They check their [GitLab todo list](https://docs.gitlab.com/ee/user/todos.html) to see any mentions or tasks assigned to them, collaborating with other stakeholders in their organization. These tasks can include:\n\n- managing infrastructure\n- maintaining the configuration of resources\n- maintaining CI/CD pipelines\n- automating processes for efficiency\n- maintaining monitoring and alerting systems\n- ensuring applications are securely built and deployed\n- modernizing applications with containerization\n\nTo carry out these tasks, DevOps engineers spend a lot of time reading documentation, writing configuration files, and searching for help in forums, issues boards, and blogs. Time is spent studying and understanding concepts, and how tools and technologies work. When they don't work as expected, a lot more time is spent investigating why. New tools are released regularly to solve niche or existing problems differently, which introduces more things to learn and maintain context for.\n\n[GitLab Duo](https://about.gitlab.com/gitlab-duo/), our AI-powered suite of capabilities, fits into the workflow of DevSecOps engineers, enabling them to reduce time spent solving problems while increasing their efficiency.\n\nLet's explore how GitLab Duo helps streamline workflows.\n\n## Collaboration and communication\n\nDiscussions or requests for code reviews require spending time reading comments from everyone and carefully reviewing the work shared. GitLab Duo capabilities like Discussion Summary, Code Review Summary, and Merge Request Summary increase the effectiveness of collaboration by reducing the time required to get caught up on activities and comments, with more time spent getting the actual work done.\n\n### Merge Request Summary  \n\nWriting a detailed and clear summary of the change a merge request introduces is crucial for every stakeholder to understand what, why, and how a change was made. It's more difficult than it sounds to effectively articulate every change made, especially in a large merge request. [Merge Request Summary](https://docs.gitlab.com/ee/user/project/merge_requests/duo_in_merge_requests.html#generate-a-description-by-summarizing-code-changes) analyzes the change's diff and provides a detailed summary of the changes made.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/4muvSFuWWL4?si=1i2pkyqXZGn2dSbd\" title=\"GitLab Duo Chat is now aware of Merge Requests\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n### Discussion Summary\n\nImagine getting pulled into an issue with more than 100 comments and a lengthy description, with different perspectives and opinions shared. GitLab Duo [Discussion Summary](https://docs.gitlab.com/ee/user/discussions/index.html#summarize-issue-discussions-with-duo-chat) summarizes all the conversations in the issue and identifies tasks that need to be done, reducing time spent. \n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/IcdxLfTIUgc?si=WXlINow3pLoKHBVM\" title=\"GitLab Duo Dicussion Summary\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n#### Code Review Summary\n\nA merge request has been assigned to a DevOps engineer for review in preparation for deployment, and they have spent time reviewing several parts of the change with multiple comments and suggestions. When [submitting a review](https://docs.gitlab.com/ee/user/project/merge_requests/reviews/index.html#submit-a-review), a text box is presented to summarize the review, which often requires taking a pause and articulating the review. With [Code Review Summary](https://docs.gitlab.com/ee/user/project/merge_requests/reviews/index.html#submit-a-review), they get a concise summary automatically drafted leading to efficiency.\n\n## Manage infrastructure changes\n\nPart of a DevOps engineer's workflow is managing infrastructure changes. Infrastructure as code ([IaC](https://docs.gitlab.com/ee/user/infrastructure/iac/)) revolutionized this process, allowing for documentation, consistency, faster recovery, accountability, and collaboration. A challenge with IaC is understanding the requirements and syntax of the chosen tool and provider where the infrastructure will be created. A lot of time is then spent reviewing documentation and tweaking configuration files until they meet expectations. \n\nWith GitLab Duo [Code Explanation](https://docs.gitlab.com/ee/user/gitlab_duo/index.html#code-explanation) and [Code Suggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions/index.html), you can prompt GitLab Duo to create configuration files in your tool of choice and learn about the syntax of those tools. With Code Suggestions, you can either leverage [code generation](https://docs.gitlab.com/ee/user/project/repository/code_suggestions/index.html#code-generation), where you prompt GitLab Duo to generate the configuration, or code completion, which provides suggestions as you type while maintaining the context of your existing configurations.\n\nAs of the time this article was published, Terraform is [supported by default](https://docs.gitlab.com/ee/user/project/repository/code_suggestions/supported_extensions.html#supported-languages) with the right extensions for your IDEs. Other technologies can be supported with [additional language support configuration](https://docs.gitlab.com/ee/user/project/repository/code_suggestions/supported_extensions.html#add-support-for-more-languages) for the [GitLab Workflow extension](https://docs.gitlab.com/ee/editor_extensions/visual_studio_code/index.html).\n\nWhere a technology is not officially supported, [GitLab Duo Chat](https://docs.gitlab.com/ee/user/gitlab_duo_chat/examples.html) is the powerful AI assistant that can help generate, explain, clarify, and troubleshoot your configuration, while maintaining context from selected text or opened files. Here are two demos where GitLab Duo helped create IaC with Terraform and AWS CloudFormation.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/saa2JJ57UaQ?si=Bu9jyQWwuSUcw8vr\" title=\"Manage your Infrastructure with Terraform and AI using GitLab Duo\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n\u003Cbr>\u003C/br>\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/KSLk2twXqiI?si=QDdERjbM0f7X2p23\" title=\"Deploying AWS Lambda function using AWS Cloudformation with help from GitLab Duo\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n### Configuration management\n\nOnce your infrastructure is up, GitLab Duo Chat can also help create configuration files and refactor existing ones. These can be Ansible configurations for infrastructure or cloud-native configurations using Docker, Kubernetes, or Helm resource files. In the videos below, I demonstrate how GitLab Duo helps with Ansible, containerization, and application deployment to Kubernetes.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/t6ZCq_jkBwY?si=awCUdu1wCgOO21XR\" title=\"Configuring your Infrastructure with Ansible & GitLab Duo\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n\u003Cbr>\u003C/br>\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/KSLk2twXqiI?si=QDdERjbM0f7X2p23\" title=\"Containerizing your application with GitLab Duo\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n\u003Cbr>\u003C/br>\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/uroSxvMFqPU?si=GMNC7f2b7i_cjn6F\" title=\"Deploying your application to Kubernetes with Help from GitLab Duo\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n\u003Cbr>\u003C/br>\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/9yGDM00RlUA?si=kE5JZD_OEFcxeR7E\" title=\"Deploying to Kubernetes using Helm with help from GitLab Duo\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n### Test, test, test\n\nWriting tests is an important part of building secure software, but it can be a chore and often becomes an afterthought. You can leverage the power of GitLab Duo to [generate tests for your code](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/index.html#vulnerability-resolution) by highlighting your code and typing the `/tests` in the Chat panel of your IDE.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/zWhwuixUkYU?si=wI93j90PIiUMyGcV\" title=\"GitLab Duo Test Generation\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n### CI/CD pipeline troubleshooting\n\nAutomation is an essential part of the DevOps engineer's workflow, and Continuous Integration/Deployment ([CI/CD](https://about.gitlab.com/topics/ci-cd/)) is central to this. You can trigger CI jobs on code push, merge, or on schedule. But, when jobs fail, you spend a lot of time reading through the logs to identify why, and for cryptic errors, it can take more time to figure out. [GitLab Duo Root Cause Analysis](https://about.gitlab.com/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd/) analyzes your failed job log and errors, and then recommends possible fixes. This reduces the time spent investigating the errors and finding a fix.\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/Sa0UBpMqXgs?si=IyR-skz9wJMBSicE\" title=\"GitLab Duo Root Cause Analysis\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n### Building secure applications\n\nPart of software development includes discovering vulnerabilities, either in the application or its dependencies. Some vulnerabilities are easy to fix, while others require creating a milestone with planning. GitLab Duo [Vulnerability Explanation](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/index.html#explaining-a-vulnerability) and [Vulnerability Resolution](https://docs.gitlab.com/ee/user/application_security/vulnerabilities/index.html#vulnerability-resolution) reduce the time spent researching and fixing vulnerabilities. Vulnerability Explanation explains why a vulnerability is happening, its impact, and how to fix it, helping the DevOps engineer to upskill. Vulnerability Resolution takes it further – instead of just suggesting a fix, it creates a merge request with a fix for the vulnerability for you to review. \n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/MMVFvGrmMzw?si=Fxc4SeOkCBKwUk_k\" title=\"GitLab Duo Vulnerability Explanation\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n\u003Cbr>\u003C/br>\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/VJmsw_C125E?si=XT3Qz5SsX-ISfCyq\" title=\"GitLab Duo Vulnerability resolution\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## More work done with less stress\n\nWith GitLab Duo, DevOps engineers can do more work deploying and maintaining secure applications, while acquiring more skills with the detailed responses from GitLab Duo Chat.\n\n> [Sign up for a free trial of GitLab Duo](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/) to get started today!",[717,109,9,496,827,848],{"slug":3461,"featured":91,"template":698},"streamline-devsecops-engineering-workflows-with-gitlab-duo","content:en-us:blog:streamline-devsecops-engineering-workflows-with-gitlab-duo.yml","Streamline Devsecops Engineering Workflows With Gitlab Duo","en-us/blog/streamline-devsecops-engineering-workflows-with-gitlab-duo.yml","en-us/blog/streamline-devsecops-engineering-workflows-with-gitlab-duo",{"_path":3467,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3468,"content":3474,"config":3479,"_id":3481,"_type":14,"title":3482,"_source":16,"_file":3483,"_stem":3484,"_extension":19},"/en-us/blog/structuring-the-gitlab-package-registry-for-enterprise-scale",{"title":3469,"description":3470,"ogTitle":3469,"ogDescription":3470,"noIndex":6,"ogImage":3471,"ogUrl":3472,"ogSiteName":686,"ogType":687,"canonicalUrls":3472,"schema":3473},"Structuring the GitLab Package Registry for enterprise scale","Learn how to leverage GitLab's unique project-based publishing model alongside root-group-level consumption to create a secure, flexible package management strategy.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662332/Blog/Hero%20Images/blog-image-template-1800x945__23_.png","https://about.gitlab.com/blog/structuring-the-gitlab-package-registry-for-enterprise-scale","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Structuring the GitLab Package Registry for enterprise scale\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Tim Rizzi\"}],\n        \"datePublished\": \"2025-02-19\",\n      }",{"title":3469,"description":3470,"authors":3475,"heroImage":3471,"date":3476,"body":3477,"category":848,"tags":3478},[2096],"2025-02-19","As organizations grow, managing internal packages becomes increasingly\ncomplex. While traditional package managers, like JFrog Artifactory and\nSonatype Nexus, use a centralized repository approach, GitLab takes a\ndifferent path that aligns with modern development teams' work. In this\npost, we'll explore how to effectively structure your GitLab Package\nRegistry for enterprise scale, focusing on Maven and npm packages as\nexamples.\n\n\n## Understanding the GitLab Package Registry model\n\n\nIf you're coming from a traditional package manager, GitLab's approach might\ninitially seem different. Instead of a single centralized repository, GitLab\nintegrates package management directly into your existing project and group\nstructure. This means:\n\n\n- Teams publish packages to specific projects where the code lives\n\n- Teams consume packages from root group registries that aggregate all\npackages below them\n\n- Access control inherits from your existing GitLab permissions\n\n\nThis model offers several advantages:\n\n\n- Clear ownership of packages alongside their source code\n\n- Granular access control without additional configuration\n\n- Simplified CI/CD integration\n\n- Natural alignment with team structures\n\n- Single URL for accessing all company packages through root group\nconsumption\n\n\n### The power of root group package registry\n\n\nWhile GitLab supports package consumption at various group levels, using the\nroot group level has emerged as a best practice among our users. Here's why:\n\n\n- **Single access point:** One URL provides access to all private packages\nacross your organization\n\n- **Consistent package naming:** Group-level endpoints allow teams to\nmaintain their preferred naming conventions without conflicts\n\n- **Simplified configuration:** All developers can use the same\nconfiguration to access packages\n\n- **Secure access management:** Combines with deploy tokens for easy\nrotation and access control\n\n- **Hierarchical organization**: Naturally maps to your organizational\nstructure while maintaining unified access\n\n\n## Real-world example: Enterprise structure\n\n\nLet's look at how this works in practice with a large enterprise:\n\n\n```\n\ncompany/ (root group)\n\n├── retail-division/\n\n│   ├── shared-libraries/     # Division-specific shared code\n\n│   └── teams/\n\n│       ├── checkout/        # Team publishes packages here\n\n│       └── inventory/       # Team publishes packages here\n\n├── banking-division/\n\n│   ├── shared-libraries/    # Division-specific shared code\n\n│   └── teams/\n\n│       ├── payments/       # Team publishes packages here\n\n│       └── fraud/         # Team publishes packages here\n\n└── shared-platform/        # Enterprise-wide shared code\n    ├── java-commons/      # Shared Java libraries\n    └── ui-components/     # Shared UI components\n```\n\n\n### Publishing configuration\n\n\nTeams publish packages to their specific project registries, maintaining\nclear ownership:\n\n\n1. Maven example\n\n\n```xml\n\n\u003C!-- checkout/pom.xml -->\n\n\u003CdistributionManagement>\n    \u003Crepository>\n        \u003Cid>gitlab-maven\u003C/id>\n        \u003Curl>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven\u003C/url>\n    \u003C/repository>\n\u003C/distributionManagement>\n\n```\n\n\n2. npm example\n\n\n```json\n\n// ui-components/package.json\n\n{\n  \"name\": \"@company/ui-components\",\n  \"publishConfig\": {\n    \"registry\": \"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/\"\n  }\n}\n\n```\n\n\n### Consuming configuration\n\n\nThe power of root group consumption comes into play here. All teams\nconfigure a single endpoint for package access:\n\n\n1. Maven example\n\n\n```xml\n\n\u003C!-- Any project's pom.xml -->\n\n\u003Crepositories>\n    \u003Crepository>\n        \u003Cid>gitlab-maven\u003C/id>\n        \u003Curl>https://gitlab.example.com/api/v4/groups/company/-/packages/maven\u003C/url>\n    \u003C/repository>\n\u003C/repositories>\n\n```\n\n\n2. npm example\n\n\n```\n\n# Any project's .npmrc\n\n@company:registry=https://gitlab.example.com/api/v4/groups/company/-/packages/npm/\n\n```\n\n\nThis configuration automatically provides access to all packages across your\norganization while maintaining the benefits of project-based publishing.\n\n\n## Authentication and access control\n\n\nGitLab's model simplifies authentication through deploy tokens and CI/CD\nintegration.\n\n\n### For CI/CD pipelines\n\n\nGitLab automatically handles authentication in pipelines using\n`CI_JOB_TOKEN`:\n\n\n```yaml\n\n# .gitlab-ci.yml\n\npublish:\n  script:\n    - mvn deploy  # or npm publish\n  # CI_JOB_TOKEN provides automatic authentication\n```\n\n\n### For development\n\n\nUse group deploy tokens for package consumption:\n\n\n- Create read-only deploy tokens at the root group level\n\n- Rotate tokens periodically for security\n\n- Share a single configuration across all developers\n\n\n## Benefits of root group package registry\n\n\n1. Simplified configuration\n   - One URL for all package access\n   - Consistent setup across teams\n   - Easy token rotation\n2. Clear ownership\n   - Packages stay with their source code\n   - Teams maintain control over publishing\n   - Version history tied to project activity\n3. Natural organization\n   - Matches your company structure\n   - Supports team autonomy\n   - Enables cross-team collaboration\n\n## Getting started\n\n\n1. Set up your root group\n   - Create a clear group structure\n   - Configure appropriate access controls\n   - Create group deploy tokens\n2. Configure team projects\n   - Set up project-level publishing\n   - Implement CI/CD pipelines\n   - Document package naming conventions\n3. Standardize consumption\n   - Configure root group registry access\n   - Share deploy tokens securely\n   - Document package discovery process\n\n## Summary\n\n\nGitLab's package registry model, particularly when leveraging root group\nconsumption, offers a powerful solution for enterprise package management.\nBy combining project-based publishing with root group consumption,\norganizations get the best of both worlds: clear ownership and simplified\naccess. This approach scales naturally with your organization while\nmaintaining security and ease of use.\n\n\nStart by implementing this model with a single team or division, and expand\nas you see the benefits of this integrated approach. Remember that while\nthis post focused on Maven and npm, the same principles apply to all package\ntypes supported by GitLab.\n\n\n> Get started with package registries today! Sign up for a [free\ntrial of GitLab Ultimate](https://about.gitlab.com/free-trial/).\n",[9,827,1259],{"slug":3480,"featured":91,"template":698},"structuring-the-gitlab-package-registry-for-enterprise-scale","content:en-us:blog:structuring-the-gitlab-package-registry-for-enterprise-scale.yml","Structuring The Gitlab Package Registry For Enterprise Scale","en-us/blog/structuring-the-gitlab-package-registry-for-enterprise-scale.yml","en-us/blog/structuring-the-gitlab-package-registry-for-enterprise-scale",{"_path":3486,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3487,"content":3492,"config":3497,"_id":3499,"_type":14,"title":3500,"_source":16,"_file":3501,"_stem":3502,"_extension":19},"/en-us/blog/summarize-my-merge-request-review",{"title":3488,"description":3489,"ogTitle":3488,"ogDescription":3489,"noIndex":6,"ogImage":839,"ogUrl":3490,"ogSiteName":686,"ogType":687,"canonicalUrls":3490,"schema":3491},"ML experiment: Summarize my merge request review","Learn how GitLab is experimenting with ML-powered merge request review summaries in this latest installment of our ongoing 'AI/ML in DevSecOps' series.","https://about.gitlab.com/blog/summarize-my-merge-request-review","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"ML experiment: Summarize my merge request review\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Kai Armstrong\"}],\n        \"datePublished\": \"2023-05-18\",\n      }",{"title":3488,"description":3489,"authors":3493,"heroImage":839,"date":3494,"body":3495,"category":781,"tags":3496},[1592],"2023-05-18","\n\n\u003Ci>This blog is the latest post in an ongoing series about GitLab’s journey to \u003Ca href=\"/blog/ai-ml-in-devsecops-series/\">build and integrate AI/ML into our DevSecOps platform\u003C/a>. The first blog post can be found \u003Ca href=\"/blog/what-the-ml-ai/\">here\u003C/a>. Throughout the series, we’ll feature blogs from our product, engineering, and UX teams to showcase how we’re infusing AI/ML into GitLab.\u003C/i>\n\nDuring the course of reviewing a merge request, you may sometimes leave many comments. Those comments may have specific information about things that need to be changed, or context for why you're leaving feedback on the proposed changes. If you've left a lot of comments, it might be hard to remember everything you've said and what the author should look at to resolve your feedback.\n\nIn a rapid prototype, [Stanislav Lashmanov](https://gitlab.com/slashmanov), Senior Frontend Engineeer for our [Code Review Group](https://handbook.gitlab.com/handbook/product/categories/#code-review-group), used AI/ML to summarize your merge request review when [submitting your review](https://docs.gitlab.com/ee/user/project/merge_requests/reviews/#submit-a-review). He developed a new AI action that provides a summary, and allows you to edit or revise prior to submitting the review:\n\n![Summarize my merge request review via AI](https://about.gitlab.com/images/blogimages/summarize-my-merge-request-review-ai.gif){: .shadow}\n\nProviding authors with these review summaries allows them to quickly understand the feedback and scope of revisions required without the need to process the entire review. This helps to speed up the cycle time for teams as they work through review rounds in merge requests.\n\n## Iterating on AI/ML features\n\nWhile just an experiment today, we are iterating on how to effectively bring features like this to our customers. We'll continue to refine the type of review feedback we provide, and then look at how we can better integrate these summaries in to the review cycle. You can see some of our [design efforts](https://gitlab.com/gitlab-org/gitlab/-/issues/408307) we've been exploring with the [summarizing merge request changes](/blog/merge-request-changes-summary-ai/) feature to get an idea of our possible direction.\n\nThis experiment is just the start of the ways we're infusing GitLab with AI/ML capabilities to help GitLab users become more efficient and effective at their jobs. We are [looking across the software development lifecycle](/blog/what-the-ml-ai/) for painful and time-consuming tasks that are ideal for AI-assisted features. We'll continue to share these demos throughout this blog series.\n\nInterested in using these AI-generated features? [Join our waitlist](https://forms.gle/9eeUkPJauKsbLaoz5) and share your ideas.\n\nContinue reading our \"[AI/ML in DevSecOps](/blog/ai-ml-in-devsecops-series/)\" series.\n\n_Disclaimer: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._\n",[9,848,719,717],{"slug":3498,"featured":6,"template":698},"summarize-my-merge-request-review","content:en-us:blog:summarize-my-merge-request-review.yml","Summarize My Merge Request Review","en-us/blog/summarize-my-merge-request-review.yml","en-us/blog/summarize-my-merge-request-review",{"_path":3504,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3505,"content":3511,"config":3516,"_id":3518,"_type":14,"title":3519,"_source":16,"_file":3520,"_stem":3521,"_extension":19},"/en-us/blog/supercharge-productivity-with-gitlab-duo",{"title":3506,"description":3507,"ogTitle":3506,"ogDescription":3507,"noIndex":6,"ogImage":3508,"ogUrl":3509,"ogSiteName":686,"ogType":687,"canonicalUrls":3509,"schema":3510},"Supercharge productivity with generative AI and GitLab Duo","Learn how the GitLab DevSecOps platform leverages generative AI and large language models to enable organizations to boost productivity and efficiency.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674838/Blog/Hero%20Images/duo-blog-post.png","https://about.gitlab.com/blog/supercharge-productivity-with-gitlab-duo","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Supercharge productivity with generative AI and GitLab Duo\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Abubakar Siddiq Ango\"}],\n        \"datePublished\": \"2023-07-20\",\n      }",{"title":3506,"description":3507,"authors":3512,"heroImage":3508,"date":3513,"body":3514,"category":781,"tags":3515},[1455],"2023-07-20","\nIn GitLab's [2023 Global DevSecOps Report](https://about.gitlab.com/developer-survey/), developer productivity and operational efficiency were top of mind for most respondents and ranked as the two top benefits organizations strive for when adopting DevSecOps methodologies. At the same time, artificial intelligence (AI) and machine learning (ML) have become highly relevant to research and development teams in recent years and have gained increased importance in the software development process of many companies. Across the software development lifecycle, generative AI is enabling faster development cycles, less time spent on code reviews, and more secure software development practices.\n\nAt GitLab, we’re using generative AI and ML to deliver productivity and efficiency gains to DevSecOps teams throughout the software development lifecycle. In this blog post, we will look at how the suite of [GitLab Duo](https://about.gitlab.com/gitlab-duo/) AI capabilities boost productivity. First, let's understand the underlying technology: generative AI.\n\n## What is generative AI?\nGenerative AI is a branch of AI capable of generating new content. The generated content is created by using patterns learned from examples or input data during the training process. One of the most popular architectures used to learn from data is a [transformer model](https://blogs.nvidia.com/blog/what-is-a-transformer-model/). Given the success of transformer models in natural language processing (NLP) and their flexibility in being adapted or fine-tuned to different and more specific tasks, they have been called \"foundation models,\" a term coined by Stanford researchers in an [August 2021 research paper](https://arxiv.org/pdf/2108.07258.pdf).\n\nThese models, when trained on text data, are capable of learning context and meaning by tracking relationships in the input data. A successful application of transformer models is [large language models (LLMs)](https://www.nvidia.com/en-us/glossary/data-science/large-language-models/): algorithms trained with petabyte-scale, text-based data sets to recognize, predict, and generate various forms of content. Examples of LLMs include Google’s [PaLM 2](https://blog.google/technology/ai/google-palm-2-ai-large-language-model/), OpenAI’s [GPT series](https://openai.com/gpt-4) and Meta’s [Llama 2](https://ai.meta.com/llama/). According to [Ark Invest](https://ark-invest.com/big-ideas-2023/artificial-intelligence/), generative AI is expected to increase the productivity of knowledge workers more than fourfold by 2030.\n\nThe GitLab DevSecOps Platform leverages generative AI and LLMs to power [GitLab Duo](https://about.gitlab.com/gitlab-duo/), a suite of AI capabilities that enable organizations to boost efficiency and ship secure software faster. Now, let’s take a look at the capabilities of GitLab Duo.\n\n## Efficient & secure software development\n\nIn a research paper looking into the impact of AI on developer productivity published in February 2023, [Peng et al.](https://arxiv.org/abs/2302.06590) found that developers who used AI-powered tools completed their tasks 55.8% faster than those who didn’t. In this section, we'll look at how GitLab Duo can help teams reduce development time, improve developer productivity, and ensure secure software development.\n\n### Code Suggestions\nEfficient developer experience is critical to productivity, and GitLab Duo [Code Suggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html) improves the developer experience and leads to shorter cycle times. If you want to import dependencies in your favourite programming language or create a function along with unit tests, Code Suggestions automatically provides suggestions in your IDE with a high degree of accuracy.\n\nCode Suggestions is currently available in Beta for all tiers on GitLab.com and in self-managed GitLab from Version 16.1. You can [use Code Suggestions with the GitLab WebIDE, Visual Studio Code](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html), and [other IDEs](https://about.gitlab.com/blog/extending-code-suggestions/).\n\n### Code explanations\nDevelopers spend a ton of time on search engines trying to figure out what a block of code does or why it behaves the way it does. The [\"explain this code\"](https://docs.gitlab.com/ee/user/ai_features.html#explain-selected-code-in-the-web-ui) feature is currently an [experiment](https://docs.gitlab.com/ee/policy/experiment-beta-support.html#experiment) on GitLab.com and uses LLMs to explain code in natural language, including context based on the code selected for it to explain.\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/xzsFfFqvlnU\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n### AI-generated tests for code changes\nEnsuring code changes are thoroughly tested is hard work and can be time-consuming. In your merge requests, with generative AI, you can generate test files for your code to provide coverage for the change introduced, reducing the time spent writing tests.\n\n![Merge request test coverage with AI](https://about.gitlab.com/images/blogimages/merge-request-generate-tests-ai.gif)\n\n### Vulnerability explanations\nA critical part of preventing the escalation of vulnerabilities is understanding why vulnerabilities were discovered and how to fix them. This takes much effort to research before making an informed decision on the next action step. [GitLab Duo vulnerability recommendations](https://about.gitlab.com/blog/explain-this-vulnerability/) provide detailed information on identified vulnerabilities, including context from your code, how they can be exploited, and example fixes, thus allowing quick remediation of vulnerabilities.\n\n![Explain this vulnerability](https://about.gitlab.com/images/blogimages/2023-04-27-explain-this-vulnerability.png)\n\n### Value stream forecasting\n\nThe efficiency of the software development lifecycle is critical to a team’s productivity and quality of value delivery. It is critical for software leaders to identify trends from events occuring in the lifecycle and implement changes to improve efficiency. GitLab’s [Value Streams Dashboard](https://docs.gitlab.com/ee/user/analytics/value_streams_dashboard.html) allows teams to track software performance and the flow of value across the software development lifecycle with [DORA metrics](https://docs.gitlab.com/ee/user/analytics/dora_metrics.html), [value stream analytics](https://docs.gitlab.com/ee/user/group/value_stream_analytics/index.html), and [vulnerability reports](https://gitlab.com/gitlab-org/gitlab/-/security/vulnerability_report).\n\n## Improved code review processes\n\n[In a 2019 survey](https://static1.smartbear.co/smartbearbrand/media/pdf/the-2019-state-of-code-review.pdf), 55% of respodents were either indifferent to or dissatisfied by their team’s code review process, and this is largely due to code reviews being seen as added work ([necessary but often time-consuming](https://codeclimate.com/blog/time-wasting-code-review)). In this section, we'll look at how GitLab Duo can help reduce review cycles and increase speed.\n\n### Merge request change summary\n\nOnce your changes are ready for review, you create a merge request, which allows you to collaborate with other stakeholders. Merge request descriptions often give the context on why the changes were made, but sometimes don’t include details of the changes themselves, except if you look at the code. Leveraging AI and LLMs, GitLab can provide relevant summaries of merge requests, reducing time spent ensuring the merge request description is up to date as changes evolve. All you need to do is use the `/summarize_diff` [quick action](https://docs.gitlab.com/ee/user/project/quick_actions.html) to add a summary of changes in a comment.\n\n![Merge request changes summary with AI](https://about.gitlab.com/images/blogimages/merge-request-changes-summary-ai.gif)\n\n### Issue comment summary\n\nWhen planning work, discussion is an essential element of collaboration. Discussions can become lengthy and catching up on all the comments can be a challenge, especially in an organization with an asynchronous culture. Similar to summarizing merge request changes, GitLab can [summarize issue comments](https://about.gitlab.com/blog/summarize-issues/), which is valuable in efficiently understanding the status of work from the issue discussions and the next steps to take. Here is a video of how it works:\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/GMr3eHwbYAI\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n### Suggested reviewers\nIdentifying reviewers can be time-consuming, especially with cross-functional collaborations in a large team. When enabled by project maintainers or owners, GitLab [suggests reviewers](https://docs.gitlab.com/ee/user/project/merge_requests/reviews/index.html#suggested-reviewers) for a merge request based on the code changes made and the project’s contribution graph. This leads to higher-quality feedback from team members with domain knowledge and increases the speed of reviews.\n\n### Merge request review summary\nCode reviewers often leave feedback across several parts of the changes they’ve reviewed, then proceed to write a separate comment to give an overview of all the feedback given. The reviewer spends valuable time ensuring the merge request author has the context to understand the review. With GitLab Duo, the reviewer can simply use the [\"summarize my code review\"](/blog/summarize-my-merge-request-review/) capability to provide authors with context around the feedback, without the need to process the entire review.\n\n![Summarize code review](https://about.gitlab.com/images/blogimages/summarize-my-merge-request-review-ai.gif)\n\n## What's coming next\nGitLab is continuously iterating on our [AI-assisted capabilities](https://about.gitlab.com/blog/ai-ml-in-devsecops-series/) to find innovative ways to enable you to efficiently build more secure software faster, while putting privacy first in a single application that gives every stakeholder visibility. This includes AI [experiments](https://docs.gitlab.com/ee/policy/experiment-beta-support.html#experiment) such as [GitLab Duo Chat](https://docs.gitlab.com/ee/user/ai_features.html#gitlab-duo-chat), which uses generative AI to answer product-specific questions about GitLab, reducing time spent reviewing the GitLab documentation. Another experiment is the \"fill in merge request description\" capability, which uses AI and content from the proposed changes to fill in a merge request decription template.\n\n![Summarize MR Descriptions](https://about.gitlab.com/images/blogimages/summarize-mr-description.gif)\n\nGitLab Duo’s AI-assisted workflows enable teams in every phase of the software development lifecycle to deliver secure software faster with increased efficiency and reduced cycle times. Learn more about [GitLab Duo here](https://about.gitlab.com/gitlab-duo/).\n",[9,496,717],{"slug":3517,"featured":6,"template":698},"supercharge-productivity-with-gitlab-duo","content:en-us:blog:supercharge-productivity-with-gitlab-duo.yml","Supercharge Productivity With Gitlab Duo","en-us/blog/supercharge-productivity-with-gitlab-duo.yml","en-us/blog/supercharge-productivity-with-gitlab-duo",{"_path":3523,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3524,"content":3530,"config":3535,"_id":3537,"_type":14,"title":3538,"_source":16,"_file":3539,"_stem":3540,"_extension":19},"/en-us/blog/the-gitlab-quarterly-how-our-latest-beta-releases-support-developers",{"title":3525,"description":3526,"ogTitle":3525,"ogDescription":3526,"noIndex":6,"ogImage":3527,"ogUrl":3528,"ogSiteName":686,"ogType":687,"canonicalUrls":3528,"schema":3529},"The GitLab Quarterly: How our latest beta releases support developers","The Value Streams Dashboard and Remote Development provide the capabilities needed to support DevSecOps teams and stay competitive.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749668367/Blog/Hero%20Images/innovation-unsplash.jpg","https://about.gitlab.com/blog/the-gitlab-quarterly-how-our-latest-beta-releases-support-developers","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"The GitLab Quarterly: How our latest beta releases support developers\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Dave Steer\"}],\n        \"datePublished\": \"2023-01-24\",\n      }",{"title":3525,"description":3526,"authors":3531,"heroImage":3527,"date":3532,"body":3533,"category":10,"tags":3534},[886],"2023-01-24","\nIt’s easy to say that 2023 will be the year of innovation, but with the macroeconomic environment requiring an obsessive eye on cost efficiencies, and in some cases, cost-cutting, exactly how are organizations supposed to stay competitive when it comes to software development and delivery? The answer is clear: Stay focused on supporting your developers. Our two new beta releases help you do just that.\n\nThe GitLab Value Streams Dashboard, now available in private beta, ensures that all stakeholders have visibility, early and in real time, into the progress and value delivery metrics associated with software development and delivery. With everyone on the same page, discussions can be had and adjustments made before developers face obstacles or stall out waiting for decision-makers to get up to speed. Developers can also see, at-a-glance, their impact on the idea-to-customer value chain. The goal: Reduce idle time so that developers can spend more time developing and IT leaders can better unlock their transformation results. Keeping the creativity flowing can boost developer happiness and help provide a glide path for software to make its way into the market and add value. \n\nOur other beta release, GitLab Remote Development, can enable organizations to directly support developers by letting them establish an environment that best suits their needs, including where, when, and how they prefer to work. GitLab Remote Development doesn’t require developers to set up and manage local development environments, which keeps workflow distractions to a minimum. Stripping away location, device, and complex toolchain barriers can maximize developer satisfaction, which can lead to increased ingenuity and productivity.\n\nAn overarching aspect of this developer support is that it is available on a single DevSecOps platform so you don’t have to tack on something special to achieve these goals — the tools are all there and ready to be used to create better software faster.\n\nNow, let’s dig deeper into these capabilities and how they will help you support your developers and deliver value to your customers.\n\n## GitLab Value Streams Dashboard\n\nIn many conversations we have with customers, lack of visibility into metrics for software development value streams comes up as a pain point. Value streams – the process from idea to delivering customer value – should be the epicenter for understanding the progress, blockers, timelines, and costs associated with your development projects. Without this insight, innovation with an eye to cost efficiencies is virtually impossible. It is also difficult to properly support developers through fast, informed decision-making if everyone doesn’t have access to the same real-time data. \n\nThe GitLab Value Streams Dashboard gives stakeholders a bird's-eye view of their teams’ software delivery metrics (such as [DORA metrics](https://docs.gitlab.com/ee/user/analytics/dora_metrics.html) and [flow metrics](https://docs.gitlab.com/ee/user/analytics/value_stream_analytics.html)) for continuous improvement. DevSecOps teams can identify and fix inefficiencies and bottlenecks in their software delivery workflows, which can improve the overall productivity and stability of their development environment. \n\n> \"Our team is excited to try out the DORA metrics capabilities available in the private beta for the new Value Streams Dashboard. We look forward to using other widgets as the Value Streams Dashboard matures, which we hope will greatly improve our productivity and efficiency.\"  \n> _**Rob Fulwell, Staff Engineer, Conversica**_\n\nThe first iteration of the GitLab Value Streams Dashboard enables teams to continuously improve software delivery workflows by benchmarking key DevOps metrics to help improve productivity, efficiency, scalability, and performance. Tracking and comparing these metrics over a period of time helps teams catch downward trends early, drill down into individual projects/metrics, take remedial actions to maintain their software delivery performance, and track progress of their innovation investments.\n\nLeadership can support developers by using information from the dashboard to cross-pollinate and promote best practices, add resources to projects based on metrics, and eliminate common bottlenecks across projects. \n\n\n\n### Roadmap for Value Streams Dashboard\n\nWe are just getting started with delivering capabilities in our Value Streams Dashboard. The roadmap includes planned features and functionality that will continue to improve decision-making and operational efficiencies.\n\nHere are some of the capabilities we plan to focus on next:\n\n1. New visualizations such as overview widgets, [top view treemap](https://gitlab.com/gitlab-org/gitlab/-/issues/381306), and [DORA performance score chart](https://gitlab.com/gitlab-org/gitlab/-/issues/386843)\n2. Security and vulnerability benchmarking  to enable executives to better understand an organization’s security exposure \n3. A new [data warehouse](https://gitlab.com/groups/gitlab-org/-/epics/9318?_gl=1*1orel9k*_ga*ODExMTUxMDcwLjE2Njk3MDM3Njk.*_ga_ENFH3X7M5Y*MTY3MjkxMTgxMC43Ny4xLjE2NzI5MTI0MTIuMC4wLjA.) that supports fast analytical queries and deep data analysis\n4. Additional business value metrics such as adoption, OKRs, revenue, costs, CSAT that align technical and business goals\n\n[Learn more on our direction page](/direction/plan/value_stream_management/).\n\n### Join the beta: We welcome your contributions\n\nAs we iterate on this new offering, GitLab Premium and Ultimate customers are invited to [join our private beta](https://about.gitlab.com/solutions/value-stream-management/).\n\nWe also invite you to learn more about [Value Streams Dashboard](https://docs.gitlab.com/ee/user/analytics/value_streams_dashboard.html) and [follow along](https://gitlab.com/groups/gitlab-org/-/epics/9317) on the timeline to General Availability.\n\n## GitLab Remote Development\n\nThe increasing adoption of reproducible, ephemeral, cloud-based development environments has accelerated software development. But for developers, frequent context-switching between different environments, navigating complex and extensive toolchains, and managing a local development environment can create friction. GitLab Remote Development helps organizations better support developers by enabling them to spend less time managing their development environment and more time contributing high-quality code.\n\n> \"While a number of stakeholders are critical to successful DevOps, software developers are key for a successful DevOps implementation. Thus, organizations must adequately support developers. This means providing good developer experiences that are not disruptive or intrusive, but that are nonetheless sanctioned by the company, and that remain secure and compliant through automation and abstraction.\"  \n> _**Jay Lyman, 451 Research, a part of S&P Global Market Intelligence, \"Traditional IT teams, leadership stand out as additional DevOps stakeholders – Highlights from VotE: DevOps,\" January 4, 2023**_ \n\nThe centerpiece of GitLab Remote Development is our newly released Web IDE Beta, now the default web IDE experience on GitLab. The Web IDE makes it possible to securely connect to a remote development environment, run commands in an interactive terminal panel, and get real-time feedback from right inside the Web IDE. Understanding that developer familiarity is important, the Web IDE Beta uses a more powerful VS code interface and is able to handle many of the most frequently performed tasks on the existing Web IDE, including committing changes to multiple files and reviewing merge request diffs.\n\nGitLab Remote Development also creates a more secure development experience by enabling organizations to implement a [zero-trust policy](/blog/why-devops-and-zero-trust-go-together/) that prevents source code and sensitive data from being stored locally across numerous developer devices. In addition, organizations can adhere to compliance requirements by ensuring developers are working with approved environments, libraries, and dependencies. \n\nIt’s interesting to note that we deployed the Web IDE beta turned on as default and currently 99.9% of users have kept it toggled on. I encourage you to learn more about the [new Web IDE functionality](/blog/get-ready-for-new-gitlab-web-ide/) in our recent blog post. \n\n### Roadmap for Remote Development\n\nAs iteration continues on the GitLab remote development experience, the roadmap currently focuses on the following functionality next: \n\n1. Provision instances of remote development environments on demand in the customer’s choice of cloud provider.\n2. Allow teams to share complex, multi-repo environments.\n3. Connect from a variety of IDEs, including VS Code, JetBrains, Vim, or the Web IDE.\n4. Ensure an organization’s remote environments conform to its software supply chain security requirements with advanced security tools, authorization, reports, and audit logs.\n\n[Learn more on our direction page](/direction/create/ide/remote_development/).\n\n## Engage with DevSecOps experts\n\nWant to dig deeper into how to innovate while still keeping an eye on cost efficiencies? Join me for our webcast “[GitLab’s DevSecOps Innovations and Predictions for 2023](https://page.gitlab.com/webcast-gitlab-devsecops-innovations-predictions-2023.html?utm_medium=blog&utm_source=gitlab&utm_campaign=devopsgtm&utm_content=fy23q4release)” on Jan. 31 to get expert advice and insights about this era of DevSecOps transformation and the tools and strategies you’ll need to meet this challenge. \n\n[Register today](https://page.gitlab.com/webcast-gitlab-devsecops-innovations-predictions-2023.html?utm_medium=blog&utm_source=gitlab&utm_campaign=devopsgtm&utm_content=fy23q4release)!\n\n**Disclaimer**: This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab.\n\n\n_Cover image by [Skye Studios](https://unsplash.com/@skyestudios?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com)_\n  \n",[1299,9,1039,719],{"slug":3536,"featured":6,"template":698},"the-gitlab-quarterly-how-our-latest-beta-releases-support-developers","content:en-us:blog:the-gitlab-quarterly-how-our-latest-beta-releases-support-developers.yml","The Gitlab Quarterly How Our Latest Beta Releases Support Developers","en-us/blog/the-gitlab-quarterly-how-our-latest-beta-releases-support-developers.yml","en-us/blog/the-gitlab-quarterly-how-our-latest-beta-releases-support-developers",{"_path":3542,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3543,"content":3549,"config":3555,"_id":3557,"_type":14,"title":3558,"_source":16,"_file":3559,"_stem":3560,"_extension":19},"/en-us/blog/the-ultimate-guide-to-sboms",{"title":3544,"description":3545,"ogTitle":3544,"ogDescription":3545,"noIndex":6,"ogImage":3546,"ogUrl":3547,"ogSiteName":686,"ogType":687,"canonicalUrls":3547,"schema":3548},"The ultimate guide to SBOMs","Learn what a software bill of materials is and why it has become an integral part of modern software development.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664571/Blog/Hero%20Images/blog-image-template-1800x945__8_.png","https://about.gitlab.com/blog/the-ultimate-guide-to-sboms","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"The ultimate guide to SBOMs\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sandra Gittlen\"}],\n        \"datePublished\": \"2022-10-25\",\n      }",{"title":3544,"description":3545,"authors":3550,"heroImage":3546,"date":3551,"body":3552,"category":694,"tags":3553,"updatedDate":3554},[799],"2022-10-25","In today's rapidly evolving digital landscape, the emphasis on application security within the software supply chain has never been more critical. The integration of upstream dependencies into software requires transparency and security measures that can be complex to implement and manage. This is where a software bill of materials (SBOM) becomes indispensable.\n\nServing as a comprehensive list of ingredients that make up software components, an SBOM illuminates the intricate web of libraries, tools, and processes used across the development lifecycle. Coupled with vulnerability management tools, an SBOM not only reveals potential vulnerabilities in software products but also paves the way for strategic risk mitigation. Our guide dives deep into SBOMs, their pivotal role in a multifaceted [DevSecOps](/topics/devsecops/) strategy, and strategies for improving your application's SBOM health — all aimed at fortifying your organization's cybersecurity posture in a landscape full of emerging threats.\n\nYou'll learn:\n- [What is an SBOM?](#what-is-an-sbom%3F)\n- [Why SBOMs are important](#why-sboms-are-important)\n- [Types of SBOM data exchange standards](#types-of-sbom-data-exchange-standards)\n- [Benefits of pairing SBOMs and software vulnerability management](#benefits-of-pairing-sboms-and-software-vulnerability-management)\n- [GitLab and dynamic SBOMs](#gitlab-and-dynamic-sboms)\n    - [Scale SBOM generation and management](#scale-sbom-generation-and-management)\n    - [Ingest and merge SBOMs](#ingest-and-merge-sboms)\n    - [Accelerate mitigation for better SBOM health](#accelerate-mitigation-for-better-sbom-health)\n    - [Continuous SBOM analysis](#continuous-sbom-analysis)\n    - [Building trust in SBOMs](#building-trust-in-sboms)\n - [The future of GitLab SBOM functionality](#the-future-of-gitlab-sbom-functionality)\n - [Get started with SBOMs](#get-started-with-sboms)\n - [SBOM FAQ](#sbom-faq)\n\n## What is an SBOM?\n\nAn SBOM is a nested inventory or [list of ingredients that make up software components](https://www.cisa.gov/sbom#). In addition to the components themselves, SBOMs include critical information about the libraries, tools, and processes used to develop, build, and deploy a software artifact.\n\nThe SBOM concept has existed [for more than a decade](https://spdx.dev/about/). However, as part of an effort to implement the National Cyber Strategy that the White House released in 2023, [CISA’s Secure by Design framework](https://www.cisa.gov/securebydesign) is helping guide software manufacturers  to adopt secure-by-design principles and integrate cybersecurity into their products. The U.S. government [issued best practices](/blog/comply-with-nist-secure-supply-chain-framework-with-gitlab/) that are driving application developers selling to the public sector to include SBOMs with their software packages. The private sector is not far behind, sending SBOMs on the path to ubiquity. \n\nAlthough SBOMs are often created with stand-alone software, platform companies like GitLab are integrating SBOM generation early and deep in the DevSecOps workflow.\n\n![supply chain security sdlc](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749673653/Blog/Content%20Images/supply_chain_security_sdlc.png)\n\n## Why SBOMs are important\n\nModern software development is laser-focused on delivering applications at a faster pace and in a more efficient manner. This can lead to developers incorporating code from open source repositories or proprietary packages into their applications.  According to Synopsys’s 2024 Open Source Security and Risk Analysis report, which consolidated findings from more than 1,000 commercial codebases across 17 industries in 2023, 96% of the total codebases contained open source and 84% of codebases assessed for risk contained vulnerabilities.\n\nPulling in code from unknown repositories increases the potential for vulnerabilities that can be exploited by hackers. In fact, the [2020 SolarWinds attack](https://www.techtarget.com/whatis/feature/SolarWinds-hack-explained-Everything-you-need-to-know) was sparked by the activation of a malicious injection of code in a package used by SolarWinds’ Orion product. Customers across the software supply chain were significantly impacted. Other attacks, including the log4j vulnerability that impacted a number of commercial software vendors, cemented the need for a deep dive into application dependencies, including containers and infrastructure, to be able to assess [risk throughout the software supply chain](https://about.gitlab.com/blog/the-ultimate-guide-to-software-supply-chain-security/).\n\nThere is also a cost component to finding and remediating a software security vulnerability that levels up the need for SBOMs, as well as damage to a company’s reputation that a software supply chain attack can incur. SBOMs give you insight into your dependencies and can be used to look for vulnerabilities, and licenses that don’t comply with internal policies.\n\n## Types of SBOM data exchange standards\n\nSBOMs work best when their generation and interpretation of information such as name, version, packager, and more are able to be automated. This happens best if all parties use a standard data exchange format.\n\nThere are two main types of SBOM data exchange standards in use today:\n- [OWASP CycloneDX](https://cyclonedx.org/capabilities/sbom/)\n- [SPDX](https://spdx.dev/)\n\nGitLab uses CycloneDX for its SBOM generation because the standard is prescriptive and user-friendly, can simplify complex relationships, and is extensible to support specialized and future use cases. In addition, [cyclonedx-cli](https://github.com/CycloneDX/cyclonedx-cli#convert-command) and [cdx2spdx](https://github.com/spdx/cdx2spdx) are open source tools that can be used to convert CycloneDX files to SPDX if necessary.\n\n## Benefits of pairing SBOMs and software vulnerability management\n\nSBOMs are highly beneficial for DevSecOps teams and software consumers for several reasons:\n* They enable a standard approach to understanding what additional software components are in an application and where they are declared.\n* They provide ongoing visibility into the history of an application’s creation, including details about third-party code origins and host repositories.\n* They provide a deep level of security transparency into both first-party developed code and adopted open source software.\n* The details that SBOMs offer enable a DevOps team to identify vulnerabilities, assess the potential risks, and then mitigate them. \n* SBOMs can deliver the transparency that application purchasers now demand.\n\n## GitLab and dynamic SBOMs\n\nFor SBOMs to be fully impactful, organizations must be able to automatically generate them, connect them with application security scanning tools, integrate the vulnerabilities and licenses into a dashboard for easy comprehension and actionability, and update them continuously. GitLab supports all of these goals.\n\n![Dynamic SBOM management](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749673653/Blog/Content%20Images/Screenshot_2024-05-03_at_10.53.28_AM.png)\n\n### Scale SBOM generation and management\nTo comply with internal policies and regulations, it is key to have accurate and comprehensive SBOMs that cover open source, third-party, and proprietary software. To effectively manage SBOMs for each component and product version, a streamlined process is required for creating, merging, validating and approving SBOMs. GitLab’s [Dependency List feature](https://docs.gitlab.com/ee/user/application_security/dependency_list/) aggregates known vulnerability and license data into a single view within the GitLab user interface. Dependency graph information is also generated as part of the dependency scanning report. This empowers users to gain comprehensive insights into dependencies and risk within their projects or across groups of projects. Additionally, a JSON CycloneDX formatted artifact can be produced in the CI pipeline. This API introduces a more nuanced and customizable approach to SBOM generation. SBOMs are exportable from the UI, a specific pipeline or project, or via the GitLab API. \n\n### Ingest and merge SBOMs\nGitLab can ingest third-party SBOMs, providing a deep level of security transparency into both third-party developed code and adopted open source software. With GitLab, you can use a [CI/CD](https://about.gitlab.com/topics/ci-cd/) job to seamlessly merge multiple CycloneDX SBOMs into a single SBOM. Using implementation-specific details in the CycloneDX metadata of each SBOM, such as the location of build and lock files, duplicate information is removed from the resulting merged file. This data is also augmented automatically with license and vulnerability information for the components inside the SBOM.\n\n### Accelerate mitigation for better SBOM health\nBuilding high-quality products faster requires actionable security findings so developers can address the most critical weaknesses. GitLab helps secure your supply chain by [scanning for vulnerabilities](https://docs.gitlab.com/ee/user/application_security/secure_your_application.html) in source code, containers, dependencies, and running applications. GitLab offers full security scanner coverage from Static Application Security Testing (SAST), Dynamic Application Security Testing (DAST), container scanning, and software composition analysis (SCA) features to help you achieve full coverage against emerging threat vectors.\nTo help developers and security engineers better understand and remediate vulnerabilities more efficiently, [GitLab Duo](https://about.gitlab.com/gitlab-duo/) Vulnerability Explanation, an AI-powered feature, provides an explanation about a specific vulnerability, how it can be exploited, and, most importantly, a recommendation on how to fix the vulnerability. When combined with GitLab Duo Vulnerability Resolution, DevSecOps teams can intelligently identify, analyze, and fix vulnerabilities in just a matter of clicks.\n\nThe platform also supports creation of new policies (and [compliance enforcement](https://docs.gitlab.com/ee/administration/compliance.html)) based on newly detected vulnerabilities. \n\n### Continuous SBOM analysis \nGitLab Continuous Vulnerability Scanning triggers a scan on all projects where either container scanning, dependency scanning, or both, are enabled independent of a pipeline.  When new Common Vulnerabilities and Exposures (CVEs) are reported to the National Vulnerability Database (NVD), users don’t need to re-run their pipelines to get the latest feeds. GitLab’s Vulnerability Research Team adds them to GitLab’s Advisory Database and those advisories are automatically reported up to GitLab as vulnerabilities. This makes GitLab’s SBOM truly dynamic in nature. \n\n### Building trust in SBOMs\nOrganizations that require [compliance functionality](https://about.gitlab.com/solutions/compliance/) can use GitLab to [generate attestation for all build artifacts](/blog/securing-the-software-supply-chain-through-automated-attestation/) produced by the GitLab Runner. The process is secure because it is produced by the GitLab Runner itself with no handoff of data to an external service.\n\n## The future of GitLab SBOM functionality\n\nSoftware supply chain security continues to be a critical topic in the cybersecurity and software industry due to frequent attacks on large software vendors and the focused efforts of attackers on the open source software ecosystem. And although the SBOM industry is evolving quickly, there are still concerns around how SBOMs are generated, the frequency of that generation, where they are stored, how to combine multiple SBOMs for complex applications, how to analyze them, and how to leverage them for application health.\n\nGitLab has made SBOMs an integral part of its [software supply chain direction](https://about.gitlab.com/direction/supply-chain/) and continues to improve upon its SBOM capabilities within the DevSecOps platform, including planning new features and functionality. Recent enhancements to SBOM capabilities include the automation of attestation, digital signing for build artifacts, and support for externally generated SBOMs.\n\nGitLab has also established a robust [SBOM Maturity Model](https://handbook.gitlab.com/handbook/security/security-assurance/dedicated-compliance/sbom-plan/) within the platform that involves steps such as automatic SBOM generation, sourcing SBOMs from the development environment, analyzing SBOMs for artifacts, and advocating for the digital signing of SBOMs. GitLab also plans to add automatic digital signing of build artifacts in future releases. \n\n## Get started with SBOMs\n\nThe demand for SBOMs is already high. Government agencies increasingly recommend or require SBOM creation for software vendors, federal software developers, and even open source communities.\n\n> To get ahead of this requirement, check out the SBOM capabilities for GitLab Ultimate in [GitLab’s DevSecOps platform](https://gitlab.com/-/trials/new).\n\n## SBOM FAQ\n\n**What is an SBOM?**\n\nAn SBOM is a detailed inventory that lists all components, libraries, and tools used in creating, building, and deploying software. This comprehensive list goes beyond mere listings to include vital information about code origins, thus promoting a deeper understanding of an application's makeup and potential vulnerabilities.\n\n**Why are SBOMs important?**\n\nSBOMs are crucial for several reasons. They provide:\n- Insight into dependencies: Understanding what makes up your software helps identify and mitigate risks associated with third-party components.\n- Enhanced security: With detailed visibility into application components, organizations can pinpoint vulnerabilities quickly and take steps to address them.\n- Regulatory compliance: Increasingly, regulations and best practices recommend or require an SBOM for software packages, particularly for those in the public sector.\n- Streamlined development: Developers can lean on an SBOM for insights into used libraries and components, saving time and reducing errors in the development cycle.\n\n**What standards are used for SBOM data exchange?**\n\nThere are two predominant standards:\n- CycloneDX: Known for its user-friendly approach, CycloneDX simplifies complex relationships between software components and supports specialized use cases.\n- SPDX: Another widely used framework for SBOM data exchange, providing detailed information about components within the software environment.\n\nGitLab specifically employs CycloneDX for its SBOM generation because of its prescriptive nature and extensibility to future needs.\n\n**What is GitLab’s approach to SBOMs?**\n\nGitLab emphasizes the creation of dynamic SBOMs that can be:\n- Automatically generated: Ensuring up-to-date information on software composition.\n- Integrated with tools: Connecting to vulnerability scanning tools for thorough risk assessment.\n- Easily managed: Supporting ingestion and merging of SBOMs for comprehensive analysis.\n- Continuously analyzed: Offering ongoing scanning of projects to detect new vulnerabilities as they emerge.\n\n**How can I start implementing SBOMs in my organization?**\n\nFor organizations ready to adopt SBOMs, GitLab’s Ultimate package provides a robust platform for generating and managing SBOMs within a DevSecOps workflow. By leveraging GitLab’s tools, teams can ensure compliance, enhance security, and optimize development practices.\n\nThe increasing demand for SBOMs reflects the growing emphasis on software security and supply chain integrity. By integrating SBOM capabilities, organizations can better protect themselves against vulnerabilities and comply with emerging regulations.\n\n> [Try GitLab Ultimate free today.](https://about.gitlab.com/free-trial/devsecops/)\n\n_Disclaimer This blog contains information related to upcoming products, features, and functionality. It is important to note that the information in this blog post is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned in this blog and linked pages are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab._",[694,9,1039,803,186],"2024-05-02",{"slug":3556,"featured":6,"template":698},"the-ultimate-guide-to-sboms","content:en-us:blog:the-ultimate-guide-to-sboms.yml","The Ultimate Guide To Sboms","en-us/blog/the-ultimate-guide-to-sboms.yml","en-us/blog/the-ultimate-guide-to-sboms",{"_path":3562,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3563,"content":3568,"config":3573,"_id":3575,"_type":14,"title":3576,"_source":16,"_file":3577,"_stem":3578,"_extension":19},"/en-us/blog/there-is-no-mlops-without-devsecops",{"title":3564,"description":3565,"ogTitle":3564,"ogDescription":3565,"noIndex":6,"ogImage":1053,"ogUrl":3566,"ogSiteName":686,"ogType":687,"canonicalUrls":3566,"schema":3567},"Building GitLab with GitLab: Why there is no MLOps without DevSecOps","Follow along as data scientists adopt DevSecOps practices and enjoy the benefits of automation, repeatable workflows, standardization, and automatic provisioning of infrastructure.","https://about.gitlab.com/blog/there-is-no-mlops-without-devsecops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Building GitLab with GitLab: Why there is no MLOps without DevSecOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"William Arias\"}],\n        \"datePublished\": \"2023-10-05\",\n      }",{"title":3564,"description":3565,"authors":3569,"heroImage":1053,"date":3570,"body":3571,"category":781,"tags":3572},[3015],"2023-10-05","Building predictive models requires a good amount of experimentation and\niterations. Data scientists building those models usually implement\nworkflows involving several steps such as data loading, processing,\ntraining, testing, and deployment. Such workflows or data science pipelines\ncome with a set of challenges on their own; some of these common challenges\nare:\n\n- prone to error due to manual steps\n\n- experimentation results that are hard to replicate\n\n- long training time of machine learning (ML) models \n\n\nWhen there is a challenge, there is also an opportunity; in this case, those\nchallenges represent an opportunity for data scientists to adopt DevSecOps\npractices and enjoy the benefits of automation, repeatable workflows,\nstandardization, and automatic provisioning of infrastructure needed for\ndata-driven applications at scale.\n\n\nThe [Data Science team at\nGitLab](https://about.gitlab.com/handbook/business-technology/data-team/organization/data-science/)\nis now utilizing the GitLab DevSecOps Platform in their workflows,\nspecifically to:\n\n- enhance experiment reproducibility by ensuring code and data execute in a\nstandardized container image\n\n- automate training and re-training of ML models with GPU-enabled CI/CD\n\n- leverage ML experiment tracking, storing the most relevant metadata and\nartifacts produced by data science pipelines automated with CI\n\n\nAt GitLab, we are proponents of \"dogfooding\" our platform and sharing how we\nuse GitLab to build GitLab. What follows is a detailed look at the Data\nScience team's experience.\n\n\n### Enhancing experiment reproducibility \n\nA baseline step to enhance reproducibility is having a common and standard\nexperiment environment for all data scientists to run experiments in their\nJupyter Notebooks. A standard data science environment ensures that all team\nmembers use the same software dependencies. A way to achieve this is by\nbuilding a container image with all the respective dependencies under\nversion control and re-pulling it every time a new version of the code is\nrun. This process is illustrated in the figure below:\n\n\n![build](https://about.gitlab.com/images/blogimages/2023-10-04-there-is-no-mlops-without-devsecops/build-2.png)\n\nData science image of automatic build using GitLab CI \n\n{: .note.text-center}\n\n\nYou might wonder if the image gets built every time there is a new commit.\nThe answer is \"no\" since that would result in longer execution times, and\nthe image dependencies versions don’t change frequently, rendering it\nunnecessary to build it every time there is a new commit. Therefore, once\nthe standard image is automatically built by the pipeline, it is pushed to\nthe GitLab Container Registry, where it is stored and ready to be pulled\nevery time changes to the model code are introduced, and re-training is\nnecessary.\n\n\n![registry](https://about.gitlab.com/images/blogimages/2023-10-04-there-is-no-mlops-without-devsecops/registry.png)\n\nGitLab Container Registry with image automatically built and pushed by a CI\npipeline\n\n{: .note.text-center}\n\n\nChanges to the image dependencies or Dockerfile require a [merge\nrequest](https://docs.gitlab.com/ee/user/project/merge_requests/) and an\napproval process.\n\n\n### How to build the data science image using GitLab CI/CD\n\nConsider this project structure:\n\n\n```\n\nnotebooks/\n\n.gitlab-ci.yml\n\nDockerfile\n\nconfig.yml\n\nrequirements.txt\n\n```\n\nGitLab's Data Science team already had a pre-configured JupyterLab image\nwith packages such as [gitlabds](https://pypi.org/project/gitlabds/1.0.0/)\nfor common data preparation tasks and modules to enable Snowflake\nconnectivity for loading raw data. All these dependencies are reflected in\nthe Dockerfile at the root of the project, plus all the steps necessary to\nbuild the image: \n\n\n```\n\nFROM nvcr.io/nvidia/cuda:12.1.1-base-ubuntu22.04\n\nCOPY .    /app/\n\nWORKDIR /app\n\nRUN apt-get update\n\nRUN apt-get install -y python3.9\n\nRUN apt-get install -y python3-pip\n\nRUN pip install -r requirements.txt\n\n```\n\n\nThe instructions to build the data science image start with using Ubuntu\nwith CUDA drivers as a base image. We are using this baseline image because,\nmoving forward, we will use GPU hardware to train models. The rest of the\nsteps include installing Python 3.9 and the dependencies listed in\n`requirements.txt` with their respective versions. \n\n\nAutomatically building the data science image using [GitLab\nCI/CD](https://about.gitlab.com/topics/ci-cd/) requires us to create the\n`.gitlab-ci.yml ` at the root of the project and use it to describe the jobs\nwe want to automate. For the time being, let’s focus only on the\n`build-ds-image`job:\n\n\n```\n\nvariables:\n  DOCKER_HOST: tcp://docker:2375\n  MOUNT_POINT: \"/builds/$CI_PROJECT_PATH/mnt\"\n  CONTAINER_IMAGE: \"$CI_REGISTRY_IMAGE/main-image:latest\"\n\nstages:\n    - build\n    - train\n    - notify\ninclude:\n  - template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml'\nworkflow:\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS\n      when: never\n\nbuild-ds-image:\n  tags: [ saas-linux-large-amd64 ]\n  stage: build\n  services:\n    - docker:20.10.16-dind\n  image:\n    name: docker:20.10.16\n  script:\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n    - docker build -t $CONTAINER_IMAGE .\n    - docker push $CONTAINER_IMAGE\n  rules:\n    - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'\n      changes:\n       - Dockerfile\n       - requirements.txt\n\n  allow_failure: true\n```\n\n\nAt a high level, the job `build-ds-image`:\n\n- uses a docker-in-docker service (dind) necessary to create docker images\nin GitLab CI/CD.\n\n- uses [predefined variables](link) to log into the GitLab Container\nRegistry, build the image, tag it using $CONTAINER_IMAGE variable, and push\nit to the registry. These steps are declared in the script section lines.\n\n- leverages a  `rules` section to evaluate conditions to determine if the\njob should be created. In this case, this job runs only if there are changes\nto the Dockerfile and requirements.txt file and if those changes are created\nusing a merge request.\n\n\nThe conditions declared in `rules` helps us optimize the pipeline running\ntime since the image gets rebuilt only when necessary.\n\n\nA complete pipeline can be found in this example project, along with\ninstructions to trigger the automatic creation of the data science image:\n[Data Science CI\npipeline](https://gitlab.com/gitlab-data/data-science-ci-example/-/blob/main/.gitlab-ci.yml?ref_type=heads).\n\n\n### Automate training and re-training of ML models with GPU-enabled CI/CD\n\nGitLab offers the ability to leverage GPU hardware and, even better, to get\nthis hardware automatically provisioned to run jobs declared in the\n.gitlab-ci.yml file. We took advantage of this capability to train our ML\nmodels faster without spending time setting up or configuring graphics card\ndrivers. Using GPU hardware ([GitLab\nRunners](https://docs.gitlab.com/ee/ci/runners/saas/gpu_saas_runner.html))\nrequires us to add this line to the training job: \n\n\n```\n\ntags:\n        - saas-linux-medium-amd64-gpu-standard\n```\n\n\nThe tag above will ensure that a GPU GitLab Runner automatically picks up\nevery training job.\n\nLet’s take a look at the entire training job in the .gitlab-ci.yml file and\nbreak down what it does:\n\n\n```\n\ntrain-commit-activated:\n    stage: train\n    image: $CONTAINER_IMAGE\n    tags:\n        - saas-linux-medium-amd64-gpu-standard\n    script:\n        - echo \"GPU training activated by commit message\"\n        - echo \"message passed is $CI_COMMIT_MESSAGE\"\n        - notebookName=$(echo ${CI_COMMIT_MESSAGE/train})\n        - echo \"Notebook name $notebookName\"\n        - papermill -p is_local_development False -p tree_method 'gpu_hist' $notebookName -\n    rules:\n        - if: '$CI_COMMIT_BRANCH == \"staging\"'\n          when: never\n        - if: $CI_COMMIT_MESSAGE =~ /\\w+\\.ipynb/\n          when: always\n          allow_failure: true\n    artifacts:\n      paths:\n        - ./model_metrics.md\n````\n\n\nLet’s start with this block:\n\n\n```\n\ntrain-commit-activated:\n    stage: train\n    image: $CONTAINER_IMAGE\n    tags:\n        - saas-linux-medium-amd64-gpu-standard\n```\n\n\n- **train-commit-activated** This is the name of the job. Since the model\ntraining gets activated given a specific pattern in the commit message, we\nuse a descriptive name to easily identify it in the larger pipeline.\n\n- **stage: train** This specifies the pipeline stage where this job belongs.\nIn the first part of the CI/CD configuration, we defined three stages for\nthis pipeline: `build`, `train`,  and `notify`. This job comes after\nbuilding the data science container image. The order is essential since we\nfirst need the image built to run our training code in it.\n\n- **image: $CONTAINER_IMAGE** Here, we specify the Docker image built in the\nfirst job that contains the CUDA drivers and necessary Python dependencies\nto run this job. $CONTAINER_IMAGE is a user-defined variable specified in\nthe variables section of the .gitlab-ci.yml file. \n\n- **tags: saas-linux-medium-amd64-gpu-standard** As mentioned earlier, using\nthis line, we ask GitLab to automatically provision a GPU-enabled Runner to\nexecute this job.\n\n\nThe second block of the job:\n\n\n```\n\nscript:\n        - echo \"GPU training activated by commit message\"\n        - echo \"message passed is $CI_COMMIT_MESSAGE\"\n        - notebookName=$(echo ${CI_COMMIT_MESSAGE/train})\n        - echo \"Notebook name $notebookName\"\n        - papermill -p is_local_development False -p tree_method 'gpu_hist' $notebookName -\n```\n\n\n- **script** This section contains the commands in charge of running the\nmodel training. The execution of this job is conditioned to the contents of\nthe  commit message. The commit message must have the name of the Jupyter\nNotebook that contains the actual model training code.\n\n\nThe rationale behind this approach is that we wanted to keep the data\nscientist workflow as simple as possible. The team had already adopted the\n[modeling\ntemplates](https://gitlab.com/gitlab-data/data-science/-/tree/main/templates)\nto start building predictive models quickly. Plugging the CI pipeline into\ntheir modeling workflow was a priority to ensure productivity would remain\nintact. With these steps:\n\n\n```\n\nnotebookName=$(echo ${CI_COMMIT_MESSAGE/train})\n        - echo \"Notebook name $notebookName\"\n        - papermill -p is_local_development False -p tree_method 'gpu_hist' $notebookName -\n```\n\n\nThe CI pipeline captures the name of the Jupyter Notebook with the training\nmodeling template and passes parameters to ensure\n[XGBoost](https://xgboost.readthedocs.io/en/stable/) uses the provisioned\nGPU. You can find an example of the Jupyter modeling template that is\nexecuted in this job\n[here](https://gitlab.com/gitlab-data/data-science-ci-example/-/blob/main/notebooks/training_example.ipynb?ref_type=heads).\n\n\nOnce the data science image is built, it can be reutilized in further model\ntraining jobs. The `train-commit-activated` job pulls the image from the\nGitLab Container Registry and utilizes it to run the ML pipeline defined in\nthe training notebook. This is illustrated in the `CI Job - Train model` in\nthe figure below:\n\n\n![training](https://about.gitlab.com/images/blogimages/2023-10-04-there-is-no-mlops-without-devsecops/training_job.png)\n\nTraining job executes ML pipeline defined in the modeling notebook\n\n{: .note.text-center}\n\n\nSince our image contains CUDA drivers and GitLab automatically provisions\nGPU-enabled hardware, the training job runs significantly faster with\nrespect to standard hardware.\n\n\n### Using GitLab ML experiment tracker\n\nEach model training execution triggered using GitLab CI is an experiment\nthat needs tracking. Using Experiment tracking in GitLab helps us to record\nmetadata that comes in handy to compare model performance and collaborate\nwith other data scientists by making result experiments available for\neveryone and providing a detailed history of the model development.\n\n\n![experiments](https://about.gitlab.com/images/blogimages/2023-10-04-there-is-no-mlops-without-devsecops/experiments.png)\n\nExperiments automatically logged on every CI pipeline GPU training run \n\n{: .note.text-center}\n\n\nEach model artifact created can be traced back to the pipeline that\ngenerated it, along with its dependencies:\n\n\n![traceability](https://about.gitlab.com/images/blogimages/2023-10-04-there-is-no-mlops-without-devsecops/traceability_small.png)\n\nModel traceability from pipeline run to candidate details\n\n{: .note.text-center}\n\n\n### Putting it all together\n\nWhat is machine learning without data to learn from? We also leveraged the\n[Snowflake](https://www.snowflake.com/en/) connector in the model training\nnotebook and automated the data extraction whenever the respective commit\ntriggers a training job. Here is an architecture of the current solution\nwith all the parts described in this blog post:\n\n\n![process](https://about.gitlab.com/images/blogimages/2023-10-04-there-is-no-mlops-without-devsecops/training_fixed.png)\n\nData Science pipelines automated using GitLab DevSecops Platform\n\n{: .note.text-center}\n\n\n| Challenge | Solution |\n\n| ------ | ------ | \n\n|Prone to error due to manual steps | Automate steps with [GitLab\nCI/CD](https://docs.gitlab.com/ee/ci/) |\n\n|Experimentation results that are hard to replicate    |  Record metadata\nand model artifacts with [GitLab Experiment\nTracker](https://docs.gitlab.com/ee/user/project/ml/experiment_tracking/)   \n|\n\n|The long training time of machine learning models     |  Train models with\n[GitLab SaaS GPU\nRunners](https://docs.gitlab.com/ee/ci/runners/saas/gpu_saas_runner.html)  |\n\n\nIterating on these challenges is a first step towards MLOps, and we are at\nthe tip of the iceberg; in coming iterations, we will adopt security\nfeatures to ensure model provenance (software bill of materials) and code\nquality, and to monitor our ML workflow development with value stream\ndashboards. But so far, one thing is sure: **There is no MLOps without\nDevSecOps**.\n\n\nGet started automating your data science pipelines, follow this\n[tutorial](https://about.gitlab.com/handbook/business-technology/data-team/platform/ci-for-ds-pipelines/)\nand clone this\n[data-science-project](https://gitlab.com/gitlab-data/data-science-ci-example)\nto follow along and watch this demo of using GPU Runners to train\n[XGBoost](https://xgboost.readthedocs.io/en/stable/) model.\n\n\nSee how data scientists can train ML models with GitLab GPU-enabled Runners\n(XGBoost 5-minute demo):\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/tElegG4NCZ0?si=L1IZfx_UGv6u81Gk\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n## More \"Building GitLab with GitLab\" blogs\n\nRead more of our \"Building GitLab with GitLab\" series:\n\n- [How we use Web API fuzz\ntesting](https://about.gitlab.com/blog/building-gitlab-with-gitlab-api-fuzzing-workflow/)\n\n- [How GitLab.com inspired GitLab\nDedicated](https://about.gitlab.com/blog/building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated/)\n",[827,9,496,717],{"slug":3574,"featured":6,"template":698},"there-is-no-mlops-without-devsecops","content:en-us:blog:there-is-no-mlops-without-devsecops.yml","There Is No Mlops Without Devsecops","en-us/blog/there-is-no-mlops-without-devsecops.yml","en-us/blog/there-is-no-mlops-without-devsecops",{"_path":3580,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3581,"content":3586,"config":3591,"_id":3593,"_type":14,"title":3594,"_source":16,"_file":3595,"_stem":3596,"_extension":19},"/en-us/blog/top-10-gitlab-technical-blogs-of-2023",{"title":3582,"description":3583,"ogTitle":3582,"ogDescription":3583,"noIndex":6,"ogImage":965,"ogUrl":3584,"ogSiteName":686,"ogType":687,"canonicalUrls":3584,"schema":3585},"Top 10 GitLab technical blogs of 2023","2023 was a big year! Catch up on expert insights into DevSecOps, AI, CI/CD, and more.","https://about.gitlab.com/blog/top-10-gitlab-technical-blogs-of-2023","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Top 10 GitLab technical blogs of 2023\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sandra Gittlen\"}],\n        \"datePublished\": \"2024-01-09\",\n      }",{"title":3582,"description":3583,"authors":3587,"heroImage":965,"date":3588,"body":3589,"category":10,"tags":3590},[799],"2024-01-09","2023 brought fresh insights from experts across GitLab and beyond —  all of them focused on the challenges and opportunities facing DevSecOps teams. From Lockheed Martin to CARFAX, organizations are trying to understand and unlock the power of technologies such as artificial intelligence (AI), CI/CD, security automation, and more. Our experts provided tips, best practices, and tutorials to use throughout the software development lifecycle.\n\nHere are the top 10 technical blogs from what was an incredible year in DevSecOps innovation.\n\n**1. [Jenkins to GitLab: The ultimate guide to modernizing your CI/CD environment](https://about.gitlab.com/blog/jenkins-gitlab-ultimate-guide-to-modernizing-cicd-environment/)**\nLooking for a smooth transition from Jenkins to GitLab? Follow this step-by-step tutorial to learn how GitLab's integrated CI/CD capabilities help deliver high-quality software faster.\n\n**2. [U.S. Navy Black Pearl: Lessons in championing DevSecOps](https://about.gitlab.com/blog/u-s-navy-black-pearl-lessons-in-championing-devsecops/)**\nSigma Defense's director of engineering details what it's like to manage the U.S. Navy's Black Pearl, which uses GitLab as its DevSecOps platform. The DevSecOps champion relays his experience implementing DevSecOps and the benefits of that decision.\n\n**3. [Quickstart guide for GitLab Remote Development workspaces](https://about.gitlab.com/blog/quick-start-guide-for-gitlab-workspaces/)**\nEnabling developers to work in their preferred environments empowers DevSecOps teams to build and deliver software more efficiently. With these quickstart instructions, developers can create a workspace, use the Web IDE Terminal to install dependencies or start their server, and view their running application.\n\n**4. [Introducing the GitLab CI/CD Catalog Beta](https://about.gitlab.com/blog/introducing-the-gitlab-ci-cd-catalog-beta/)**\nCI/CD catalogs are a game-changer, allowing developers to discover, integrate, and share pre-existing CI/CD components with ease. This tutorial shows how to get the most from this new DevSecOps platform feature.\n\n**5. [Combine GitLab Flow and GitLab Duo for a workflow powerhouse](https://about.gitlab.com/blog/gitlab-flow-duo/)**\nGitLab Flow and GitLab Duo can help organizations achieve significant improvements in end-to-end workflow efficiency that can lead to higher levels of productivity, deployment frequency, code quality and overall security, and production resiliency and availability. Find out how with this step-by-step guide.\n\n**6. [Efficient DevSecOps workflows: Hands-on python-gitlab API automation](https://about.gitlab.com/blog/efficient-devsecops-workflows-hands-on-python-gitlab-api-automation/)**\nThe python-gitlab library is a useful abstraction layer for the GitLab API. Dive into hands-on examples and best practices in this tutorial.\n\n**7. [Building GitLab with GitLab: Why there is no MLOps without DevSecOps](https://about.gitlab.com/blog/there-is-no-mlops-without-devsecops/)**\nAt GitLab, we believe in the power of MLOps, especially when combined with DevSecOps. So follow along as our data scientists adopt DevSecOps practices and enjoy the benefits of automation, repeatable workflows, standardization, and automatic provisioning of infrastructure.\n\n**8. [Explore the Dragon Realm: Build a C++ adventure game with a little help from AI](https://about.gitlab.com/blog/building-a-text-adventure-using-cplusplus-and-code-suggestions/)**\nReaders are invited to create a mystical world while learning how to integrate AI into their coding environment. This tutorial demonstrates how to use GitLab Duo Code Suggestions to create a text-based adventure game, including magical locations to visit and items to procure, using C++. \n\n**9. [How GitLab's Red Team automates C2 testing](https://about.gitlab.com/blog/how-gitlabs-red-team-automates-c2-testing/)**\nThe GitLab Red Team conducts security exercises that simulate real-world threats. They apply professional development practices to using the same open source C2 tools as threat actors. In this tutorial, the GitLab Red Team shares how they implement continuous testing for the Mythic framework, their design philosophy, and a public project that can be forked for use by other Red Teams.\n\n**10. [Building GitLab with GitLab: How GitLab.com inspired Dedicated](https://about.gitlab.com/blog/building-gitlab-with-gitlabcom-how-gitlab-inspired-dedicated/)**\nThe design of GitLab Dedicated, our single-tenancy SaaS version of the DevSecOps platform, came from the lessons learned while building GitLab.com. In this peek behind the curtains, learn the considerations that sparked different decisions regarding automation, databases, monitoring, availability, and more – and what the outcome was.\n\nSign up for the GitLab newsletter using the form to the right to receive the latest blogs right in your inbox.\n",[717,109,496,9,694,827],{"slug":3592,"featured":91,"template":698},"top-10-gitlab-technical-blogs-of-2023","content:en-us:blog:top-10-gitlab-technical-blogs-of-2023.yml","Top 10 Gitlab Technical Blogs Of 2023","en-us/blog/top-10-gitlab-technical-blogs-of-2023.yml","en-us/blog/top-10-gitlab-technical-blogs-of-2023",{"_path":3598,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3599,"content":3605,"config":3613,"_id":3615,"_type":14,"title":3616,"_source":16,"_file":3617,"_stem":3618,"_extension":19},"/en-us/blog/top-ten-reasons-to-check-out-gitlab-virtual-commit",{"title":3600,"description":3601,"ogTitle":3600,"ogDescription":3601,"noIndex":6,"ogImage":3602,"ogUrl":3603,"ogSiteName":686,"ogType":687,"canonicalUrls":3603,"schema":3604},"Top Ten Reasons to Check Out GitLab's Virtual Commit","An overview of GitLab's Virtual Commit and the content available specific to public sector.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664102/Blog/Hero%20Images/gitlab-values-cover.png","https://about.gitlab.com/blog/top-ten-reasons-to-check-out-gitlab-virtual-commit","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Top Ten Reasons to Check Out GitLab's Virtual Commit\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Jim Riley\"}],\n        \"datePublished\": \"2020-09-14\",\n      }",{"title":3600,"description":3601,"authors":3606,"heroImage":3602,"date":3608,"body":3609,"category":3610,"tags":3611},[3607],"Jim Riley","2020-09-14","\n \n{::options parse_block_html=\"true\" /}\n\n \nThis year the GitLab crew stepped away from everything they knew about creating an amazing, winning conference and reworked the Commit vision to better fit in line with the needs of our changed world. The result was an incredible digital experience. Commit transformed into a 24-hour full conference program filled with practical DevOps strategies shared by leaders in development, operations, and security. Why 24-hours? GitLab has customers, partners and contacts all across the globe and the Commit team saw the virtual environment as an opportunity to make certain everyone had access to all the exciting, featured content and our GitLab team in real time.\n \nGitLab customers and partners shared real world examples of how GitLab is helping their organizations innovate, survive, and succeed @ speed. [Login](https://gitlabcommitvirtual.com/) to view the top ten presentations that showcase how Public Sector is leading digital transformation through GitLab.\n \n - Nicolas Chaillan, Chief Software Officer, US Air Force, United States Air Force and his keynote talk  “DevSecOps in Government and Highly Regulated Industries” \n - How The U.S. Army Cyber School Created ‘Courseware-as-Code’ With GitLab \n - Deployment & Adoption of GitLab in Government \n - DevSecOps At The Brazilian Federal Public Ministry...Exclusively With Open Source Tools \n - DevOps 101: Getting to Minimal Viable 'DevOpsness' \n - Scaling DevOps at the NSA \n - Accelerating Speed to Mission Through Low-to-High Cross Domain Collaboration \n - Enabling the Tactical Edge Through DevSecOps in a Box \n - Cloud-Native Security: Processes And Tools To Protect Modern Applications \n - DevOps 101: Getting to Minimal Viable 'DevOpsness \n \nAfter absorbing the presentations shared at Commit, if you’re finding you’d like to dive a little deeper and explore a bit more, [reach out to us](https://about.gitlab.com/company/contact/) and we’ll be happy to connect with you and keep the conversation going!\n \nTo learn more about GitLab Public Sector, please visit: https://about.gitlab.com/solutions/public-sector/\n","unfiltered",[1299,9,694,3612],"kubernetes",{"slug":3614,"featured":6,"template":698},"top-ten-reasons-to-check-out-gitlab-virtual-commit","content:en-us:blog:top-ten-reasons-to-check-out-gitlab-virtual-commit.yml","Top Ten Reasons To Check Out Gitlab Virtual Commit","en-us/blog/top-ten-reasons-to-check-out-gitlab-virtual-commit.yml","en-us/blog/top-ten-reasons-to-check-out-gitlab-virtual-commit",{"_path":3620,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3621,"content":3626,"config":3631,"_id":3633,"_type":14,"title":3634,"_source":16,"_file":3635,"_stem":3636,"_extension":19},"/en-us/blog/training-and-deploying-ai-models-with-gitlab-and-vertex-ai",{"title":3622,"description":3623,"ogTitle":3622,"ogDescription":3623,"noIndex":6,"ogImage":839,"ogUrl":3624,"ogSiteName":686,"ogType":687,"canonicalUrls":3624,"schema":3625},"Train and deploy AI models with GitLab and Google Cloud's Vertex AI","Demo of GitLab's DevSecOps capabilities combined with Vertex AI's scalable ML platform, designed with the aim of rapid and secure AI deployments.","https://about.gitlab.com/blog/training-and-deploying-ai-models-with-gitlab-and-vertex-ai","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Train and deploy AI models with GitLab and Google Cloud's Vertex AI\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Regnard Raquedan\"}],\n        \"datePublished\": \"2023-06-08\",\n      }",{"title":3622,"description":3623,"authors":3627,"heroImage":839,"date":948,"body":3629,"category":781,"tags":3630},[3628],"Regnard Raquedan","\n\u003Ci>This blog is the latest post in an ongoing series about GitLab's journey to \u003Ca href=\"/blog/ai-ml-in-devsecops-series/\">build and integrate AI/ML into our DevSecOps platform\u003C/a>. The first blog post can be found \u003Ca href=\"/blog/what-the-ml-ai/\">here\u003C/a>. Throughout the series, we'll feature blogs from our product, engineering, and UX teams to showcase how we're infusing AI/ML into GitLab.\u003C/i>\n\nMost development and engineering teams are now tasked with maintaining and deploying AI/ML-related code. In this context, the focus on security and efficiency becomes even more crucial. Companies are keen to capitalize on the benefits of AI swiftly while striving to decrease potential risks. GitLab can be used to orchestrate any AI/ML workloads, enabling teams to rapidly develop new generative AI capabilities. [GitLab recently announced a partnership with Google](https://about.gitlab.com/press/releases/2023-05-02-gitLab-and-google-cloud-partner-to-expand-ai-assisted-capabilities.html) to bring [generative AI on Google Cloud](https://cloud.google.com/ai/generative-ai) to our mutual customers.\n\nThis is a tutorial of how to use these tools to deploy an AI model with [Google Cloud's Vertex AI](https://cloud.google.com/vertex-ai) using GitLab to orchestrate the [ModelOps workload](https://about.gitlab.com/direction/modelops/). Our custom model training use case is simple introductory credit card fraud detection, a pertinent issue in the financial industry.\n\n## The solution\nOur solution is a Python-based credit card transaction fraud detection app. Once deployed, applications can use an API endpoint to make predictions on whether a submitted transaction is fraudulent or not.\n\n[Vertex AI](https://cloud.google.com/vertex-ai/docs) is Google Cloud's flagship AI/ML platform that lets users train and deploy machine learning models and AI applications. This is the platform where the API endpoint and model are hosted. While Vertex AI can handle training using prebuilt functions, this demo uses a custom training script written in Python.\n\nFor the demo’s purposes, GitLab hosts the [application source code](https://gitlab.com/gitlab-com/alliances/google/sandbox-projects/demos/vertex-ai) and helps to ensure quality and security by running the tests and scans automatically. We also use GitLab's CI/CD to execute the Python code, programmatically upload the resulting artifacts to Google Cloud Storage, and create the endpoint in Vertex AI.\n\nLet's take a high-level look at how the solution is designed and what it does:\n* Data preprocessing: To effectively detect fraudulent transactions, we address the initial imbalance in the raw transaction data. By employing the [Synthetic Minority Over-sampling Technique (SMOTE)](https://imbalanced-learn.org/stable/references/generated/imblearn.over_sampling.SMOTE.html), we duplicate instances of the minority class, enhancing the model's ability to identify patterns.\n* Model training: Using the balanced dataset, we train a [RandomForestClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html) model. This creates a 'forest' of decision trees, each based on a random subset of the training data. It outputs the mode of the classes determined by the individual trees, making it well-suited for binary outcomes, such as identifying fraudulent transactions. The trained model is stored in a Google Cloud Storage bucket for later use.\n* Model deployment: Leveraging GitLab's DevSecOps platform, model deployment becomes straightforward. By committing the code to GitLab, the trained model is automatically deployed to Vertex AI. Subsequently, the API endpoint is also established.\n\n## Prerequisites\nBefore we dive into the details, let's make sure you have everything you need to get started with deploying your AI model using GitLab and Vertex AI.\n\nHere are the requirements:\n1. Google Cloud project\n1. Google Cloud service account with these permissions:\n   1. AI Platform Admin\n   1. Service Account User\n   1. Storage Admin\n   1. Storage Object Admin\n   1. Vertex AI Administrator\n1. GitLab project\n\n\u003Ciframe width=\"560\" height=\"315\" src=\"https://www.youtube-nocookie.com/embed/p7GTsbSQWF4\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen>\u003C/iframe>\n\n## Demo walkthrough\nFollowing the [video walkthrough](https://youtu.be/p7GTsbSQWF4), here's a guide for setting up an AI pipeline with GitLab and Google Cloud's Vertex AI.\n\n### Step 1: GitLab and Google Cloud connection\nFirstly, we need GitLab to interact with Google Cloud. Insert your Google Cloud Service Account credentials into your GitLab project's environment variables (make sure they're Base64 encoded for security).\n\n### Step 2: Uploading data to Vertex AI\nMove to the Vertex AI section in Google Cloud. Here, [create and upload your dataset](https://cloud.google.com/vertex-ai/docs/tabular-data/forecasting/create-dataset). In our demo, we use a 'Tabular' dataset for 'Classification' as we're predicting credit card fraud.\n\n### Step 3: Creating the CI/CD pipeline\nBack to GitLab to structure our [CI/CD pipeline](https://gitlab.com/gitlab-com/alliances/google/sandbox-projects/demos/vertex-ai/-/ci/editor). It comprises three stages:\n\n**Test:** Quality and security checks.\n\n**Train:** Executes a Python script to train the model, outputting a .pkl  artifact.\n\n```\ntrain:\n stage: train\n script:\n   - apt-get update && apt-get install -y python3-pip python3-venv\n   - python3 -m venv venv\n   - source venv/bin/activate\n   - pip install --upgrade pip\n   - pip install pandas scikit-learn joblib imbalanced-learn google-cloud-storage\n   - python3 src/train.py\n artifacts:\n   paths:\n     - model.pkl\n```\n\n**Deploy:** Uses Google Cloud's Deep Learning platform container to deploy the trained model on Vertex AI.\n\n```\ndeploy:\n stage: deploy\n image:\n   name: us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-5\n   entrypoint: [\"\"]\n script:\n   - python src/deploy.py\n dependencies:\n   - train\n only:\n   - main\n```\n\n### Step 4: Model training\nThe [training code](https://gitlab.com/gitlab-com/alliances/google/sandbox-projects/demos/vertex-ai/-/blob/main/src/train.py), running on GitLab CI/CD, fetches data from Vertex AI, processes it, trains our RandomForestClassifier model, and saves the model to Google Cloud Storage.\n\n### Step 5: Model deployment\nThe [deployment script](https://gitlab.com/gitlab-com/alliances/google/sandbox-projects/demos/vertex-ai/-/blob/main/src/deploy.py) creates an endpoint on Vertex AI and deploys our trained model there, utilizing the service account credentials we set initially.\n\n### Step 6: Prediction testing\n\n![Screenshot of Vertex AI](https://about.gitlab.com/images/blogimages/vertex-ai-screenshot.png)\n\nFinally, within Vertex AI, navigate to your model and test its predictions using an input JSON request. If all goes well, you'll get a response from your model.\n\nThere you have it: an AI pipeline with GitLab and Google Cloud's Vertex AI. This combination of GitLab's DevSecOps capabilities with Vertex AI's scalable ML platform is designed with the aim of rapid and secure AI deployments.\n",[9,848,719,717],{"slug":3632,"featured":6,"template":698},"training-and-deploying-ai-models-with-gitlab-and-vertex-ai","content:en-us:blog:training-and-deploying-ai-models-with-gitlab-and-vertex-ai.yml","Training And Deploying Ai Models With Gitlab And Vertex Ai","en-us/blog/training-and-deploying-ai-models-with-gitlab-and-vertex-ai.yml","en-us/blog/training-and-deploying-ai-models-with-gitlab-and-vertex-ai",{"_path":3638,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3639,"content":3645,"config":3651,"_id":3653,"_type":14,"title":3654,"_source":16,"_file":3655,"_stem":3656,"_extension":19},"/en-us/blog/tutorial-automated-release-and-release-notes-with-gitlab",{"title":3640,"description":3641,"ogTitle":3640,"ogDescription":3641,"noIndex":6,"ogImage":3642,"ogUrl":3643,"ogSiteName":686,"ogType":687,"canonicalUrls":3643,"schema":3644},"Tutorial: Automate releases and release notes with GitLab","With the GitLab Changelog API, you can automate the generation of release artifacts, release notes, and a comprehensive changelog detailing all user-centric software modifications.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659978/Blog/Hero%20Images/automation.png","https://about.gitlab.com/blog/tutorial-automated-release-and-release-notes-with-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Tutorial: Automate releases and release notes with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Ben Ridley\"}],\n        \"datePublished\": \"2023-11-01\",\n      }",{"title":3640,"description":3641,"authors":3646,"heroImage":3642,"date":2655,"body":3648,"category":848,"tags":3649,"updatedDate":3650},[3647],"Ben Ridley","***2025 update** - The Changelog API has continued to evolve and now has some great new capabilities we don’t cover in this blog, such as the ability to provide custom changelogs with templated values from your commit history. [Discover more in the official Changelogs docs.](https://docs.gitlab.com/user/project/changelogs/)*\n\nWhen you develop software that users rely on, effective communication about changes with each release is essential. By keeping users informed about new features and any modifications or removals, you ensure they maximize the software's benefits and avoid encountering unpleasant surprises during upgrades.\n\nHistorically, creating release notes and maintaining a changelog has been a laborious task, requiring developers to monitor changes externally or release managers to sift through merge histories. With the GitLab Changelog API, you can use the rich history provided in our git repository to easily create release notes and maintain a changelog.\n\nIn this tutorial, we'll delve into automating releases with GitLab, covering the generation of release artifacts, release notes, and a comprehensive changelog detailing all user-centric software modifications.\n\n## Releases in GitLab\nFirst, let's explore how releases work in GitLab.\n\nIn GitLab, a release is a specific version of your code, identified by a git tag, that includes details about changes since the last release (and release notes) and any related artifacts built from that version of the code, such as Docker images, installation packages, and documentation.\n\nYou can create and track releases in GitLab using the UI by calling our Release API or by defining a special `release` job inside a CI pipeline. In this tutorial, we'll use the `release` job in a CI/CD pipeline, which allows us to extend the automation we're using in our pipelines for testing, code scanning, etc. to also perform automated releases.\n\nTo automate our releases, we first need to answer this question: Where are we going to get the information on changes made for our release notes and our changelog? The answer: Our git repository, which provides us with a rich history of development activity through commit messages and merge commit history. Let's see if we can leverage this rich history to automatically create our notes and changelogs.\n\n## Introducing commit trailers\n[Commit trailers](https://git-scm.com/docs/git-interpret-trailers) are structured entries in your git commits, created by adding simple `\u003CHEADER>:\u003CBODY>` format messages to the end of your commit. The `git` CLI tool can then parse and extract these for use in other systems. An example you might have already used is `git commit --sign-off` to sign off on a commit. This is implemented by adding a `Signed-off-by: \u003CYour Name>` trailer to the commit. We can add any arbitrary structured data here, which makes it a great place to store information that could be useful for our changelog.\n\nIn fact, if we use a `Changelog: \u003Cadded/changed/removed>` trailer in our commits, the GitLab Changelog API will parse these and use them to create a changelog for us automatically!\n\nLet's see this in action by making some changes to a real codebase and performing a release, and generating release notes and changelog entries.\n\n## Our example project\nFor the purposes of this blog, I'm using a simple Python web app repository. Let's pretend Version 1.0.0 of the application was just released and is the current version of the code. I've also created a 1.0.0 release in GitLab, which I did manually because we haven't created our automated release pipeline yet:\n\n![A screenshot of the GitLab UI showing a release for Version 1.0.0](https://about.gitlab.com/images/blogimages/2023-08-22-automated-release-and-release-notes-with-gitlab/1-0-release.png)\n\n## Making our changes\nWe're in rapid development mode, so we're going to be working on releasing Version 2.0.0 of our application today. As part of our 2.0.0 release, we're going to be adding a new feature to our app: A chatbot! And we're also going to be removing the quantum blockchain feature, because we only needed that for our first venture capital funding round. Also, we're going to be adding an automated release job to our CI/CD pipeline for our 2.0.0 release.\n\nFirst, let's remove unneeded features. I've created a merge request that contains the necessary removals. Importantly, we need to ensure we have a commit message that includes the `Changelog: removed` trailer. There's a few ways to do this, such as including it directly in a commit, or performing an interactive rebase and adding it using the CLI. But I think the easiest way in our situation is to leave it until the end and then use the `Edit commit message` button in GitLab to add the trailer to the merge commit like so:\n\n![A screenshot the GitLab UI showing a merge request removing unused features](https://about.gitlab.com/images/blogimages/2023-08-22-automated-release-and-release-notes-with-gitlab/remove-unused-features-mr.png)\n\nIf you use this method, you can also change the merge commit title to something more succinct. I've changed the title of my merge commit to 'Remove Unused Features', as this is what will appear in the changelog entry.\n\nNext, let's add some new functionality for the 2.0.0 release. Again, all we need to do is open another merge request that includes our new features and then edit the merge commit to include the `Changelog: added` trailer and edit the commit title to be more succinct:\n\n![A screenshot of the GitLab UI showing a merge request to add new functionality](https://about.gitlab.com/images/blogimages/2023-08-22-automated-release-and-release-notes-with-gitlab/add-chatbot-mr.png)\n\nNow we're pretty much ready to release 2.0.0. But we don't want to create our release manually this time. So before our release we're going to add some jobs to our `.gitlab-ci.yml` file that will perform the release for us automatically, and generate the respective release notes and changelog entries, when we tag our code with a new version like `2.0.0`.\n\n**Note:** If you want to enforce changelog trailers, consider using something like [Danger to perform automated checks for MR conventions](https://docs.gitlab.com/ee/development/dangerbot.html).\n\n## Building an automated release pipeline\nFor our pipeline to work, we need to create a project access token that will allow us to call GitLab's API to generate changelog entries. [Create a project access token with the API scope](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html#create-a-project-access-token), and then [store the token as a CI/CD variable](https://docs.gitlab.com/ee/ci/variables/#define-a-cicd-variable-in-the-ui) called `CI_API_TOKEN`. We'll reference this variable to authenticate to the API.\n\nNext, we're going to add two new jobs to our `gitlab-ci.yml` file:\n```yaml\nprepare_job:\n  stage: prepare\n  image: alpine:latest\n  rules:\n  - if: '$CI_COMMIT_TAG =~ /^v?\\d+\\.\\d+\\.\\d+$/'\n  script:\n    - apk add curl jq\n    - 'curl -H \"PRIVATE-TOKEN: $CI_API_TOKEN\" \"$CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/changelog?version=$CI_COMMIT_TAG\" | jq -r .notes > release_notes.md'\n  artifacts:\n    paths:\n    - release_notes.md\n\nrelease_job:\n  stage: release\n  image: registry.gitlab.com/gitlab-org/release-cli:latest\n  needs:\n    - job: prepare_job\n      artifacts: true\n  rules:\n  - if: '$CI_COMMIT_TAG =~ /^v?\\d+\\.\\d+\\.\\d+$/'\n  script:\n    - echo \"Creating release\"\n  release:\n    name: 'Release $CI_COMMIT_TAG'\n    description: release_notes.md\n    tag_name: '$CI_COMMIT_TAG'\n    ref: '$CI_COMMIT_SHA'\n    assets:\n      links:\n        - name: 'Container Image $CI_COMMIT_TAG'\n          url: \"https://$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA\"\n```\n\nIn the above configuration, the `prepare_job` uses `curl` and `jq` to call the GitLab Changelog API endpoint and then passes this to our `release_job` to actually create the release. To break it down further:\n- We use the project access token created earlier to call the GitLab Changelog API, which performs the generation of the release notes and we store this as an artifact.\n- We're using the `$CI_COMMIT_TAG` variable as the version. For this to work, we need to be using semantic versioning for our tags (something like `2.0.0` for example), so you'll notice I've also restricted the release job using a `rules` section that checks for a semantic version tag.\n\t- Semantic versioning is required for the GitLab Changelog API to work. It uses this format to find the most recent release to compare to our current release.\n- We use the official `release-cli` image from GitLab. The release-cli is required to use the `release` keyword in a job.\n- We use the `release` keyword to create a release in GitLab. This is a special job keyword reserved for creating a release and populating the required fields.\n- We can pass a file as an argument to the `description` of the release. In our case, it's the file we generated in the `prepare_job`, which was passed to this job as an artifact.\n- We've also included our container image that is being built earlier in the pipeline as a release asset. You can attach any assets you'd like from your build process, such as binaries or documentation by providing a URL to wherever you've uploaded them earlier in the pipeline.\n\n## Performing an automated release\nWith this setup, all we need to do to perform a release is push a tag to our repository that follows our versioning scheme. You can simply push a tag using the CLI, this example uses GitLab's UI to create a tag on the main branch. Create a tag by selecting Code -> Tags -> New Tag on the sidebar:\n![A screenshot of the GitLab UI illustrating how to create a tag](https://about.gitlab.com/images/blogimages/2023-08-22-automated-release-and-release-notes-with-gitlab/create-2-tag.png)\n\nOn creation, our pipelines will start to execute. The GitLab Changelog API will automatically generate release notes for us as markdown, which contains all the changes between this release and the previous release. Here's the resulting markdown generated in our example:\n\n```md\n## 2.0.0 (2023-08-25)\n\n### added (1 change)\n\n- [Add ChatBot](gl-demo-ultimate-bridley/super-devsecops-incorporated/simply-notes-release-demo@0c3601a45af617c5481322bfce4d71db1f911b02) ([merge request](gl-demo-ultimate-bridley/super-devsecops-incorporated/simply-notes-release-demo!4))\n\n### removed (1 change)\n\n- [Remove Unused Features](gl-demo-ultimate-bridley/super-devsecops-incorporated/simply-notes-release-demo@463d453c5ae0f4fc611ea969e5442e3298bf0d8a) ([merge request](gl-demo-ultimate-bridley/super-devsecops-incorporated/simply-notes-release-demo!3))\n```\n\nAs you can see, GitLab has extracted the entries for our release notes automatically using our git commit trailers. In addition, it's helpfully provided links back to the merge request so readers can see more details and discussion around the changes.\n\nAnd now, our final release:\n![The GitLab release UI showing a release for version 2.0.0](https://about.gitlab.com/images/blogimages/2023-08-22-automated-release-and-release-notes-with-gitlab/2-0-release.png)\n\n## Creating the changelog\nNext, we want to update our changelog (which is basically a collated history of all your release notes). You can use a `POST` request to the changelog API endpoint we used earlier to do this.\n\nYou can do this as part of your release pipeline if you like, for example by adding this to the `script` section of your prepare job:\n```sh\n'curl -H \"PRIVATE-TOKEN: $CI_API_TOKEN\" -X POST \"$CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/changelog?version=$CI_COMMIT_TAG\"\n```\n\n**Note that this will actually modify the repository.** It will create a commit to add the latest notes to a `CHANGELOG.md` file:\n![A screenshot of the repository which shows a commit updating the changelog file](https://about.gitlab.com/images/blogimages/2023-08-22-automated-release-and-release-notes-with-gitlab/changelog-api-commit.png)\n\nAnd we are done! By utilizing the rich history provided by `git` with some handy commit trailers, we can leverage GitLab's powerful API and CI/CD pipelines to automate our release process and generate release notes for us.\n\n> If you’d like to explore the project we used for this article, [you can find the project at this link](https://gitlab.com/gitlab-learn-labs/sample-projects/release-automation-demo).\n",[827,825,109,1299,9,1041],"2025-06-05",{"slug":3652,"featured":6,"template":698},"tutorial-automated-release-and-release-notes-with-gitlab","content:en-us:blog:tutorial-automated-release-and-release-notes-with-gitlab.yml","Tutorial Automated Release And Release Notes With Gitlab","en-us/blog/tutorial-automated-release-and-release-notes-with-gitlab.yml","en-us/blog/tutorial-automated-release-and-release-notes-with-gitlab",{"_path":3658,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3659,"content":3665,"config":3669,"_id":3671,"_type":14,"title":3672,"_source":16,"_file":3673,"_stem":3674,"_extension":19},"/en-us/blog/tutorial-how-to-set-up-your-first-gitlab-ci-cd-component",{"title":3660,"description":3661,"ogTitle":3660,"ogDescription":3661,"noIndex":6,"ogImage":3662,"ogUrl":3663,"ogSiteName":686,"ogType":687,"canonicalUrls":3663,"schema":3664},"Tutorial: How to set up your first GitLab CI/CD component","Use Python scripts in your GitLab CI/CD pipelines to improve usability. In this step-by-step guide, you'll learn how to get started building your own CI/CD component.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098410/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%2826%29_3lH4gZFVIGCndksN6Rlg85_1750098409928.png","https://about.gitlab.com/blog/tutorial-how-to-set-up-your-first-gitlab-ci-cd-component","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Tutorial: How to set up your first GitLab CI/CD component\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sophia Manicor\"},{\"@type\":\"Person\",\"name\":\"Noah Ing\"}],\n        \"datePublished\": \"2024-11-12\",\n      }",{"title":3660,"description":3661,"authors":3666,"heroImage":3662,"date":2712,"body":3667,"category":909,"tags":3668},[2827,821],"Do you use Python scripts in your GitLab CI pipelines? Do you want to create\npipelines at scale? This tutorial shows how to set up your first [GitLab\nCI/CD component](https://docs.gitlab.com/ee/ci/components/) to deploy Python\nscripts. \n\n\nA [CI/CD component is a reusable single pipeline configuration\nunit](https://about.gitlab.com/blog/introducing-ci-components/).\nUse components to create a small part of a larger pipeline, or even to\ncompose a complete pipeline configuration.\n\n\n# Prerequisites\n\n- Basic Python knowledge\n\n- Working knowledge of GitLab CI\n\n- 8 minutes\n\n\n## Python script \n\n\n* **[The demo Python\nscript](https://gitlab.com/demos/templates/gitlab-python-cicd-component/-/blob/main/src/script.py?ref_type=heads)**\n\n\nThis Python script utilizes a library called\n[ArgParse](https://docs.python.org/3/library/argparse.html) . ArgParse\nallows you to pass variables to script through the command line. This script\ntakes in three arguments:\n\n[Python_container_image](https://docs.gitlab.com/ee/ci/yaml/#image): This is\nthe Python container image you wish to use.\n\n[Stage](https://docs.gitlab.com/ee/ci/yaml/#stage): This is the GitLab CI\nstage in which you job will run in. \n\nName: This is your name.\n\n\n```python\n\nimport argparse\n\n\nparser = argparse.ArgumentParser(description='Python CICD Component\nBoilerplate')\n\nparser.add_argument('python_container_image', type=str,\nhelp='python:3.10-slim')\n\nparser.add_argument('stage', type=str, help='Build')\n\nparser.add_argument('persons_name', type=str, help='Noah')\n\nargs = parser.parse_args()\n\n\npython_container_image = args.python_container_image\n\nstage = args.stage\n\npersons_name = args.persons_name\n\n```\n\n\nThis will take in these three variables and print out simple statements:\n\n\n```python\n\nprint(\"You have chosen \" + python_container_image + \" as the container\nimage\")\n\nprint(\"You have chosen \" + stage + \" as the stage to run this job\")\n\nprint(\"Thank you \" + persons_name + \"! you are succesfully using GitLab CI\nwith a Python script.\")\n\n```\n\n\nTo test this script locally, you can call on the script by utilizing the\nfollowing command:\n\n\n```bash\n\npython3 src/script.py python_container_image stage name\n\n```\n\n\nModify this script accordingly if you’d like to add in your own arguments!\n\n\n## Template \n\n\n* **[Demo of\ntemplate](https://gitlab.com/demos/templates/gitlab-python-cicd-component/-/blob/main/templates/template.yml?ref_type=heads)**\n\n\n**Note:** As long as the `gitlab-ci.yml` is placed in the\ntemplates/directory, the CI/CD component will know to pick it up. We named\nour template `templates.yml`, but any name would work for this YAML file.\n\n\nNow, getting into the fun part of CI/CD components, inputs! \n[Inputs](https://docs.gitlab.com/ee/ci/yaml/inputs.html) allow you to pass\nthrough variables into your pipeline. \n\n\n```yml\n\nspec:\n  inputs:\n    python_container_image:\n      default: python:3.10-slim\n      description: \"Define any python container image\"\n    stage:\n      default: build\n      description: \"Define the stage this job will run in\"\n    persons_name:\n      default: Noah\n      description: \"Put your name here\"\n```\n\nHere we have defined the three inputs that are our arguments in our Python\nscript. You can see for each input we have added in a default value – this\nwill be what the input is set to if not overridden. If we took out this\ndefault keyword the input would become mandatory when we use our component.\nAs it is written now, adding in these inputs when we use our component is\noptional due to our default values.\n\n\nWe can also set descriptions to ensure that other developers can understand\nwhat to input when they use our component. Descriptions are optional but\nthey provide self documentation within the code itself, which is always\nnice.\n\n\nAfter we set up our inputs, let’s write the rest of our component:\n\n\n```yml\n\ncomponent:\n  image: $[[ inputs.python_container_image ]]\n  stage: $[[ inputs.stage ]]\n  before_script:\n    - pip3 install -r src/requirements.txt\n  script: python3 src/script.py $[[ inputs.python_container_image ]] $[[ inputs.stage ]] $[[ inputs.persons_name ]]\n```\n\n\nTo use inputs in our component, we need to use the syntax `$[[\ninputs.$VARIABLE ]]`. In the above code, you can see that we use inputs to\ndefine our image and stage with  `$[[ inputs.python_container_image ]]`\nand   `$[[ inputs.stage ]] `.\n\n\n```\n\nscript: python3 src/script.py $[[ inputs.python_container_image ]] $[[\ninputs.stage ]] $[[ inputs.persons_name ]]\n\n```\n\nDiving into the script section, you can see we call upon our Python script..\nWe are able to pass our inputs in with the help of the ArgParse.\n\n\nNow that you have reviewed how the Python script works and the template has\nbeen set up, it is time to use the component!\n\n\n## Using the component \n\n\n* **[A demo of including the\ncomponent](https://gitlab.com/demos/templates/gitlab-python-cicd-component/-/blob/main/.gitlab-ci.yml?ref_type=heads)\n\n\nIn order to utilize the CI/CD component we just created, we need to include\nit in the `.gitlab-ci.yml` file that is in the root of our directory. \n\n\n```\n\ninclude:\n  # include the component located in the current project from the current SHA\n  - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/template@$CI_COMMIT_SHA\n    inputs:\n      python_container_image: python:3.11-slim\n      stage: test\n      persons_name: Tanuki\n```\n\n\nOne way to include it is to call upon it locally in the current project from\nthe current `Commit SHA`. You can find other ways to [reference a component\nin our\ndocumentation](https://docs.gitlab.com/ee/ci/components/#use-a-component).\n\n\nTo override the defaults, we have passed in other inputs so we get the\ncorrect image, stage, and name for our job. \n\n\nTry and change the `persons_names` to your own and watch the pipeline run!\n\n\n![ci/cd component tutorial - pipeline\nrunning](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098419/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098418901.png)\n\n\nVoila! You have learned how to set up a basic C/ICD component utilizing a\nPython ArgParse script!\n\n\n## What's next?\n\nIn the Python script, there is a commented out GitLab Python library and OS\nlibrary. If you would like to interact with the GitLab API, you can\nuncomment these and add in a [GitLab personal access\ntoken](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html)\nto the [CI/CD variables](https://docs.gitlab.com/ee/ci/variables/) named\n`GLPAT`.\n\n\n```\n\nimport gitlab\n\nimport os\n\n```\n\nAfterwards you can then interact with the GitLab API.\n\n\n```\n\nglpat = os.environ['GLPAT']\n\n\ngl = gitlab.Gitlab(private_token=glpat)\n\n# SELF_HOSTED gl = gitlab.Gitlab(url='https://gitlab.example.com',\nprivate_token='xxxxxxxxxxxxxx')\n\ntry:\n   projects = gl.projects.list(get_all=True)\n   print(projects)\nexcept Exception as error:\n   print(\"Error:\", error)\n```\n\n\n> Learn more about CI/CD components and how to avoid building pipelines from\nscratch with the [GitLab CI/CD\nCatalog](https://about.gitlab.com/blog/ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch/). \n\n\n## Read more\n\n\n- [FAQ: GitLab CI/CD\nCatalog](https://about.gitlab.com/blog/faq-gitlab-ci-cd-catalog/)\n\n- [Introducing CI/CD Steps, a programming language for DevSecOps\nautomation](https://about.gitlab.com/blog/introducing-ci-cd-steps-a-programming-language-for-devsecops-automation/)\n\n- [A CI/CD component builder's\njourney](https://about.gitlab.com/blog/a-ci-component-builders-journey/)\n",[109,827,9,1259],{"slug":3670,"featured":91,"template":698},"tutorial-how-to-set-up-your-first-gitlab-ci-cd-component","content:en-us:blog:tutorial-how-to-set-up-your-first-gitlab-ci-cd-component.yml","Tutorial How To Set Up Your First Gitlab Ci Cd Component","en-us/blog/tutorial-how-to-set-up-your-first-gitlab-ci-cd-component.yml","en-us/blog/tutorial-how-to-set-up-your-first-gitlab-ci-cd-component",{"_path":3676,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3677,"content":3682,"config":3687,"_id":3689,"_type":14,"title":3690,"_source":16,"_file":3691,"_stem":3692,"_extension":19},"/en-us/blog/tutorial-secure-bigquery-data-publishing-with-gitlab",{"title":3678,"description":3679,"ogTitle":3678,"ogDescription":3679,"noIndex":6,"ogImage":2707,"ogUrl":3680,"ogSiteName":686,"ogType":687,"canonicalUrls":3680,"schema":3681},"Tutorial: Secure BigQuery data publishing with GitLab ","Learn how to create repeatable, auditable, and efficient processes for automating and securing BigQuery data exports.","https://about.gitlab.com/blog/tutorial-secure-bigquery-data-publishing-with-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Tutorial: Secure BigQuery data publishing with GitLab \",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Regnard Raquedan\"}],\n        \"datePublished\": \"2025-03-25\",\n      }",{"title":3678,"description":3679,"authors":3683,"heroImage":2707,"date":3684,"body":3685,"category":909,"tags":3686},[3628],"2025-03-25","GitLab offers a powerful solution for automating and securing\n[BigQuery](https://cloud.google.com/bigquery) data exports. This integration\ntransforms manual exports into repeatable, auditable processes that can\neliminate security vulnerabilities while saving valuable time. This tutorial\nexplains how to implement this solution so you can quickly reduce manual\noperations, permission issues, and security concerns with just a few lines\nof GitLab YAML code.\n\n\nFollow along with this step-by-step video:\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/gxXX-ItAreo?si=FijY9wMVppCW-18q\" frameborder=\"0\" allowfullscreen=\"true\">\u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n## The solution architecture\n\n\nOur solution leverages GitLab CI/CD pipelines to automate the secure export\nof data from BigQuery to Google Cloud Storage. Here's the high-level\narchitecture:\n\n\n1. SQL code is stored and version-controlled in GitLab.  \n\n2. After code review and approval, GitLab CI/CD pipeline executes the\ncode.  \n\n3. The pipeline authenticates with Google Cloud.  \n\n4. SQL queries are executed against BigQuery.  \n\n5. Results are exported as CSV files to Google Cloud Storage.  \n\n6. Secure links to these files are provided for authorized consumption.\n\n\n## Prerequisites\n\n\nBefore we begin, ensure you have:\n\n\n* **Google Cloud APIs enabled:** BigQuery API and Cloud Storage API  \n\n* **Service account** with appropriate permissions:  \n  * BigQuery Job User  \n  * Storage Admin  \n  * **Note:** For this demo, we're using the service account approach for authentication, which is simpler to set up. For production environments, you might consider using GitLab's identity and access management integration with Google Cloud. This integration leverages Workload Identity Federation, which provides enhanced security and is more suitable for enterprise customers and organizations.  \n* **GitLab project** ready to store your SQL code and pipeline configuration\n\n\n## Step-by-step implementation\n\n\n**1. Configure Google Cloud credentials.**\n\n\nFirst, set up the necessary environment variables in your GitLab project:\n\n\n- Go to your **GitLab project > Settings > CI/CD**.  \n\n- Expand the **Variables** section.  \n\n- Add the following variables:  \n   * `GCS_BUCKET`: Your Google Cloud Storage bucket name  \n   * `GCP_PROJECT_ID`: Your Google Cloud project ID  \n   * `GCP_SA_KEY`: Base64-encoded service account key (mark as masked)\n\n**2. Create your SQL query.**\n\n\nCreate a file named `query.sql` in your GitLab repository with your BigQuery\nSQL query. The query looks like this:\n\n\n```\n\n-- This query shows a list of the daily top Google Search terms.\n\nSELECT\n   refresh_date AS Day,\n   term AS Top_Term,\n       -- These search terms are in the top 25 in the US each day.\n   rank,\nFROM `bigquery-public-data.google_trends.top_terms`\n\nWHERE\n   rank = 1\n       -- Choose only the top term each day.\n   AND refresh_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 2 WEEK)\n       -- Filter to the last 2 weeks.\nGROUP BY Day, Top_Term, rank\n\nORDER BY Day DESC\n   -- Show the days in reverse chronological order.\n\n```\n\n\nThis query gets the top 25 search terms from Google Trends for the current\nday.\n\n\n**3. Configure the GitLab CI/CD pipeline.**\n\n\nCreate a `.gitlab-ci.yml` file in your repository root:\n\n\n```\n\nimage: google/cloud-sdk:alpine\n\n\ninclude:\n  - template: Jobs/Secret-Detection.gitlab-ci.yml  # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Secret-Detection.gitlab-ci.yml\n\nexecute:\n  stage: deploy\n  script: \n    # Set up Google Cloud authentication and install necessary components\n    - export GOOGLE_CLOUD_CREDENTIALS=$(echo $SERVICE_ACCOUNT_KEY | base64 -d)\n    - echo $GOOGLE_CLOUD_CREDENTIALS > service-account-key.json \n    - gcloud auth activate-service-account --key-file service-account-key.json \n    - gcloud components install gsutil\n    # Set the active Google Cloud project\n    - gcloud config set project $PROJECT_ID\n    # Run the BigQuery query and export the results to a CSV file\n    - bq query --format=csv --use_legacy_sql=false \u003C test.sql > results.csv\n    # Create a Google Cloud Storage bucket if it doesn't exist\n    - gsutil ls gs://${CLOUD_STORAGE_BUCKET} || gsutil mb gs://${CLOUD_STORAGE_BUCKET}\n    # Upload the CSV file to the storage bucket\n    - gsutil cp results.csv gs://${CLOUD_STORAGE_BUCKET}/results.csv\n    # Set the access control list (ACL) to make the CSV file publicly readable\n    - gsutil acl ch -u AllUsers:R gs://${CLOUD_STORAGE_BUCKET}/results.csv\n    # Define the static URL for the CSV file\n    - export STATIC_URL=\"https://storage.googleapis.com/${CLOUD_STORAGE_BUCKET}/results.csv\"\n    # Display the static URL for the CSV file\n    - echo \"File URL = $STATIC_URL\"\n\n```\n\n\n**4. Run the pipeline.**\n\n\nNow, whenever changes are merged to your main branch, the pipeline will\nprovide a link to the CSV file stored on the Google Cloud Storage bucket.\nThis file contains the result of the executed SQL query that GitLab subjects\nto security checks.\n\n\n## Benefits of this approach\n\n\n* **Security:** Authentication is handled automatically via service accounts\n(or Workload Identity Federation for enhanced security in production\nenvironments).  \n\n* **Auditability:** All data exports are tracked through GitLab commits and\npipeline logs.  \n\n* **Repeatability:** Consistent, predictable export process on every run,\nand can be scheduled.  \n\n* **Version control:** SQL queries are properly versioned and reviewed.  \n\n* **Automation:** Significantly fewer manual exports, reducing human error.\n\n\n## Try it today\n\n\nBy combining GitLab's DevSecOps capabilities with Google Cloud's BigQuery\nand Cloud Storage, you've now automated and secured your data publishing\nworkflow. This approach reduces manual operations, resolves permission\nheadaches, and addresses security concerns – all achieved with just a few\nlines of GitLab CI code.\n\n\n> Use this tutorial's [complete code\nexample](https://gitlab.com/gitlab-partners-public/google-cloud/demos/big-query-data-publishing)\nto get started now.\n",[9,496,827,1016,233,1040],{"slug":3688,"featured":91,"template":698},"tutorial-secure-bigquery-data-publishing-with-gitlab","content:en-us:blog:tutorial-secure-bigquery-data-publishing-with-gitlab.yml","Tutorial Secure Bigquery Data Publishing With Gitlab","en-us/blog/tutorial-secure-bigquery-data-publishing-with-gitlab.yml","en-us/blog/tutorial-secure-bigquery-data-publishing-with-gitlab",{"_path":3694,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3695,"content":3700,"config":3705,"_id":3707,"_type":14,"title":3708,"_source":16,"_file":3709,"_stem":3710,"_extension":19},"/en-us/blog/u-s-navy-black-pearl-lessons-in-championing-devsecops",{"title":3696,"description":3697,"ogTitle":3696,"ogDescription":3697,"noIndex":6,"ogImage":880,"ogUrl":3698,"ogSiteName":686,"ogType":687,"canonicalUrls":3698,"schema":3699},"U.S. Navy Black Pearl: Lessons in championing DevSecOps","Sigma Defense built a managed service software factory environment for the military using GitLab as its DevSecOps platform. Here's what they learned.","https://about.gitlab.com/blog/u-s-navy-black-pearl-lessons-in-championing-devsecops","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"U.S. Navy Black Pearl: Lessons in championing DevSecOps\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sandra Gittlen\"}],\n        \"datePublished\": \"2023-12-12\",\n      }",{"title":3696,"description":3697,"authors":3701,"heroImage":880,"date":3702,"body":3703,"category":972,"tags":3704},[799],"2023-12-12","Manuel Gauto, director of engineering at government contractor [Sigma Defense](https://sigmadefense.com/), is a true DevSecOps champion. As co-creator of Black Pearl, a DevSecOps environment Sigma Defense manages for the U.S. Navy, Gauto witnesses firsthand the power that combining development, security, and operations can have in modernizing and scaling software development.\n\n\"If a DevSecOps environment is done correctly - where the tooling, security and compliance, connectivity, and onboarding are all handled as part of the platform – then mission owners can focus on mastering CI/CD in the context of their mission,\" Gauto said.\n\nGauto participated in GitLab's DevSecOps World Tour in Washington, D.C., speaking with GitLab Federal CTO Joel Krooswyk about Black Pearl and how consolidating a multitude of software factories into a single managed DevSecOps cloud environment has yielded tremendous results at scale, including:\n\n- a reduction in software factory setup time from around 6 months to 3 to 5 days\n- a 10x lower cost, decreasing from around $4 million to around $400,000\n- a more secure environment because there is inherent security with Authorization to Operate (ATO)\n- faster onboarding, decreasing from as long as 5 weeks to 1 day\n\n## The origins of Black Pearl\n\nA few years ago, the Navy had numerous software factories operating concurrently. Gauto himself was involved in standing a few of them up. \"We realized that it wasn't the most efficient approach – duplicative infrastructure in four or five different places that was ultimately doing the same thing,\" he said. \n\nThe team pitched the idea of a single environment that would consolidate cloud infrastructure, address security issues, and provide connectivity. That single environment was named \"Black Pearl\" and now consists of two offerings: Lighthouse, a DevSecOps infrastructure as code/configuration as code (IaC/CaC) baseline, and Party Barge, a managed shared offering.\n\nBlack Pearl’s common software environment with ATO provides commoditized DevSecOps tooling, pipeline component templates, governance/management, logging and metrics, integration infrastructure, cloud automation, and compute resources. The GitLab DevSecOps Platform is a major part of Black Pearl, providing \"a one-stop shop\" for source code management, tasks, documentation, and security scanning. Gauto said the dashboards and visualization are particularly integral to go/no-go decisions on shipping software.\n\n\"GitLab is the kind of platform that really enables us because it is the first time, even internally with our development, that we don't have to jump around to a bunch of different tools – we can just do everything in GitLab,\" he said. \"Having everyone on one platform also enables collaborative efficiency.\"\n\nGitLab's capabilities support the fast, secure, and cost-effective standup of software factories, according to Gauto.\n\n> Want to learn more about GitLab for the public sector? [Contact us today](https://about.gitlab.com/solutions/public-sector/).\n\n## How to build a strong DevSecOps environment\n\nIn the years since Black Pearl was first launched, Gauto has learned a lot about what makes a robust and secure DevSecOps environment. He said it comes down to tearing down silos and establishing a development ecosystem, centralizing security and compliance, providing the\nability to easily and quickly onboard talent, and remaining flexible and open to innovation. \n\n### Establish a strong development ecosystem\n\nIn large organizations, especially within government agencies, software development tends to break into silos. \"You'll have units of innovation that struggle to collaborate because they may work in one environment or in one building,\" Gauto said, adding that sharing anything – code, best practices, tooling, or infrastructure – can be challenging.\n\n\"By creating a well-established, well-maintained deployment of tooling, in particular, with GitLab, people can see what other teams are doing and share more readily,\" he said. \"Instead of mailing a CD to some lab somewhere else in the country, DevSecOps teams can just say, 'Let me add you as a developer on my project and you can kick around these repositories.'\" \n\nAn ecosystem helps aggregate demand in a way that breaks down barriers to infrastructure accreditation. \"We can go to the cyber community or certification community and say, 'I'm here representing a large group of users. This is a pain point we all have and we would like to work with you to figure it out,'\" Gauto said. For example, allowing people to connect to Black Pearl over the internet from a contractor machine, government machine, or wherever. \"It should not be this difficult in an unclassified environment.\"\n\nWith a strong ecosystem, you also can build up your best practices and processes around planning (such as Agile, Scrum, and Kanban), integrating on-site and remote development, gaining authorization for software, and delivering applications to various environments.\n\n### Apply security and compliance\n\nWhen it comes to security and compliance, Gauto said the biggest thing is to be able to see the train coming down the tracks and to be as prepared as possible. \"Let's not be surprised and let's not be standing on the tracks when it gets here,\" he said. \n\nOne area where that sentiment is wholly applicable is compliance, where mandates are evolving at breakneck speed. \"We want to be prepared to provide the data and the tooling in a format that's ingestible by the right people,\" he said.\n\nHe credits GitLab for helping with this challenge. \"GitLab Ultimate lets us just bake compliance in from the start and template a bunch of stuff from the start,\" which lets customers immediately start running with compliance, he said.\n\nGitLab also supports licensing and ATO scans in a single platform. \n\n### Support rapid onboarding of talent\n\nAcross the military, there are obstacles to accessing the best DevSecOps talent, including working in buildings with no windows, and having to jump through giant hoops to be able to work on classified networks.\n\n\"I think that really limits the talent that can be brought to the table to solve some of the really hard problems we have,\" Gauto said. For Black Pearl to be successful\nin supporting the missions, it was imperative to \"enable broader access to talent and then build sustainable onboarding workflows.\"\n\nWithin the DoD, there are a lot of difficult and interesting problems that need to be solved but the\nability to collaborate across government, industry, and academia can be a limiting factor. \"There are a large number of locations where software development is being done and without a common environment to work within, work can be repeated, lost, or otherwise underutilized,\" Gauto said.\n\nBlack Pearl provides an environment for different organizations to collaborate in a way that is accessible. Black Pearl has focused on ensuring that authorized users are able to access the environment from different devices, networks, and locations without onerous access procedures. This approach fosters the development of new ideas and increases the speed to new capabilities.\n\n### Enable flexibility and innovation\n\nThe military has so many different delivery environments – from submarines to aircraft carriers – that Black Pearl has to be incredibly flexible. \"We enable everyone to manage their own kingdom and focus their efforts on pieces that are specific to their problem space,\" Gauto said. \"We know there's not one pipeline to rule all. So we provide the toolkit and let everyone tailor the solution to what they need instead of saying, 'you have to do software development this way and you have to deliver it this way.'\"\n\nBlack Pearl encourages customers to have a sense of ownership over their environments, using the building blocks of GitLab Ultimate, including CI/CD pipelines, scanning, and testing. \"We want them to get to the point where they are ready to use all the tools that we offer,\" Gauto said. They also educate the customer so that the customer can drive their own requirements rather than Black Pearl having to pitch functionality to them.\n\nFor example, the Black Pearl team closely collaborates with the developer team for The Forge, a software factory for the Navy's Aegis integrated weapons system. \"One day The Forge team said, 'We feel like we should be scanning our source code for secrets before we check it in.' Exactly.\"\n\nHe also wants to be careful to not stifle innovation or overly restrict customers. \"Not everything is a containerized business application that goes to the cloud,\" he said. He instructs his team members to \"make sure we have a strategy for providing flexibility for people that are doing something weird, because the people that are doing something weird are usually doing something cool.\" \n\nArtificial intelligence and machine learning will be a test of this philosophy. \"There are going to be some novel tools and some novel data classifications that we are going to have to iterate on quickly,\" he said.\n\n## The proven thesis\n\nGauto is proud of Black Pearl's tremendous adoption rates, which have grown 400% over the past 12 months, and believes it is proof of the concept. \"The Black Pearl thesis of a managed service that enables people to quickly start solving their own problems without worrying about the 'boring' stuff can work and is valuable,\" he said.\n\n> Learn more about [GitLab for the public sector](https://about.gitlab.com/solutions/public-sector/).\n",[9,496,694,269,186],{"slug":3706,"featured":91,"template":698},"u-s-navy-black-pearl-lessons-in-championing-devsecops","content:en-us:blog:u-s-navy-black-pearl-lessons-in-championing-devsecops.yml","U S Navy Black Pearl Lessons In Championing Devsecops","en-us/blog/u-s-navy-black-pearl-lessons-in-championing-devsecops.yml","en-us/blog/u-s-navy-black-pearl-lessons-in-championing-devsecops",{"_path":3712,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3713,"content":3719,"config":3724,"_id":3726,"_type":14,"title":3727,"_source":16,"_file":3728,"_stem":3729,"_extension":19},"/en-us/blog/ultimate-guide-to-ci-cd-fundamentals-to-advanced-implementation",{"title":3714,"description":3715,"ogTitle":3714,"ogDescription":3715,"noIndex":6,"ogImage":3716,"ogUrl":3717,"ogSiteName":686,"ogType":687,"canonicalUrls":3717,"schema":3718},"Ultimate guide to CI/CD: Fundamentals to advanced implementation","Learn how to modernize continuous integration/continuous deployment, including automating the development, delivery, and security of pipelines.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749660151/Blog/Hero%20Images/blog-image-template-1800x945__26_.png","https://about.gitlab.com/blog/ultimate-guide-to-ci-cd-fundamentals-to-advanced-implementation","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Ultimate guide to CI/CD: Fundamentals to advanced implementation\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sandra Gittlen\"}],\n        \"datePublished\": \"2025-01-06\",\n      }",{"title":3714,"description":3715,"authors":3720,"heroImage":3716,"date":3721,"body":3722,"category":10,"tags":3723},[799],"2025-01-06","Continuous integration/continuous delivery ([CI/CD](https://about.gitlab.com/topics/ci-cd/)) has revolutionized how software teams create value for their users. Gone are the days of manual deployments and integration headaches — modern development demands automation, reliability, and speed.\n\nAt its core, CI/CD is about creating a seamless pipeline that takes code from a developer's environment all the way to production and incorporates feedback in real time. [CI](https://about.gitlab.com/topics/ci-cd/benefits-continuous-integration/) helps teams catch issues early — before they become costly problems — by ensuring that code changes are frequently merged into a shared repository, automatically tested, and validated. [CD](https://about.gitlab.com/topics/ci-cd/#what-is-continuous-delivery-cd) extends this by automating deployments, making releases predictable and stress-free.\n\nRather than relying on manual processes and complex toolchains for software development, teams can use a robust CI/CD pipeline to build, test, and deploy software. And AI can streamline the process even further, automatically engineering CI/CD pipelines for consistent quality, compliance, and security checks.\n\nThis guide explains modern CI/CD pipelines, from basic principles to best practices to advanced strategies. You'll also discover how leading organizations use CI/CD for impactful results. What you learn in this guide will help you scale your DevSecOps environment to develop and deliver software in an [agile](https://about.gitlab.com/topics/ci-cd/continuous-integration-agile/), automated, and efficient manner.\n\nWhat you'll learn:\n- [What is continuous integration?](#what-is-continuous-integration%3F)\n- [What is continuous delivery?](#what-is-continuous-delivery%3F)\n- [How source code management relates to CI/CD](#how-source-code-management-relates-to-cicd)\n- [The benefits of CI/CD in modern software development](#the-benefits-of-cicd-in-modern-software-development)\n  - [Key differences between CI/CD and traditional development](#key-differences-between-cicd-and-traditional-development)\n- [Understanding CI/CD fundamentals](#understanding-cicd-fundamentals)\n  - [What is a CI/CD pipeline?](#what-is-a-cicd-pipeline%3F)\n- [Best practices for CI/CD implementation and management](#best-practices-for-cicd-implementation-and-management)\n  - [CI best practices](#ci-best-practices)\n  - [CD best practices](#cd-best-practices)\n- [How to get started with CI/CD](#how-to-get-started-with-cicd)\n- [Security, compliance, and CI/CD](#security-compliance%2C-and-cicd)\n- [CI/CD and the cloud](#cicd-and-the-cloud)\n- [Advanced CI/CD](#advanced-cicd)\n  - [Reuse and automation in CI/CD](#reuse-and-automation-in-cicd)\n  - [Troubleshooting pipelines with AI](#troubleshooting-pipelines-with-ai)\n- [How to migrate to GitLab CI/CD](#how-to-migrate-to-gitlab-cicd)\n- [Lessons from leading organizations](#lessons-from-leading-organizations)\n- [CI/CD tutorials](#cicd-tutorials)\n\n## What is continuous integration?\n\n[Continuous integration](https://about.gitlab.com/topics/ci-cd/benefits-continuous-integration/) (CI) is the practice of integrating all your code changes into the main branch of a shared source code repository early and often, automatically testing changes when you commit or merge them, and automatically kicking off a build. With continuous integration, teams can identify and fix errors and security issues more easily and much earlier in the development process.\n\n## What is continuous delivery?\n[Continuous delivery](https://about.gitlab.com/topics/ci-cd/#what-is-continuous-delivery-cd) (CD) – sometimes called _continuous deployment_ – enables organizations to deploy their applications automatically, allowing more time for developers to focus on monitoring deployment status and assure success. With continuous delivery, DevSecOps teams set the criteria for code releases ahead of time and when those criteria are met and validated, the code is deployed into the production environment. This allows organizations to be more nimble and get new features into the hands of users faster. \n\n## How source code management relates to CI/CD\n\nSource code management ([SCM](https://about.gitlab.com/solutions/source-code-management/)) and CI/CD form the foundation of modern software development practices. SCM systems like [Git](https://about.gitlab.com/blog/what-is-git-the-ultimate-guide-to-gits-role-and-functionality/) provide a centralized way to track changes, manage different versions of code, and facilitate collaboration among team members. When developers work on new features or bug fixes, they create branches from the main codebase, make their changes, and then [merge them through merge requests](https://docs.gitlab.com/ee/user/project/merge_requests/). This branching strategy allows multiple developers to work simultaneously without interfering with each other's code, while maintaining a stable main branch that always contains production-ready code.\n\nCI/CD takes the code managed by SCM systems and automatically builds, tests, and validates it whenever changes are pushed. When a developer submits their code changes, the CI/CD system automatically retrieves the latest code, combines it with the existing codebase, and runs through a series of automated checks. These typically include compiling the code, running unit tests, performing static code analysis, and checking code coverage. If any of these steps fail, the team is immediately notified, allowing them to address issues before they impact other developers or make their way to production. This tight integration between source control and continuous integration creates a feedback loop that helps maintain code quality and prevents integration problems from accumulating.\n\n## The benefits of CI/CD in modern software development\n\n[CI/CD brings transformative benefits to modern software development](https://about.gitlab.com/blog/ten-reasons-why-your-business-needs-ci-cd/) by dramatically reducing the time and risk associated with delivering new features and fixes. The continuous feedback loop gives DevSecOps teams confidence their changes are automatically validated against the entire codebase. The result is higher quality software, faster delivery times, and more frequent releases that can quickly respond to user needs and market demands.\n\nPerhaps most importantly, CI/CD fosters a culture of collaboration and transparency within software development teams. When everyone can see the status of builds, tests, and deployments in real time, it becomes easier to identify and resolve bottlenecks in the delivery process. The automation provided by CI/CD also reduces the cognitive load on developers, freeing them to focus on writing code rather than managing manual deployment processes. This leads to improved developer satisfaction and productivity, while also reducing the risk traditionally associated with the entire software release process. Teams can experiment more freely knowing rapid code reviews are part of the process and they can quickly roll back changes if needed, which encourages innovation and continuous improvement.\n\n> Get started with GitLab CI/CD. [Sign up for GitLab Ultimate](https://about.gitlab.com/free-trial/devsecops/) and try the AI-powered DevSecOps platform free.\n\n### Key differences between CI/CD and traditional development\n\nCI/CD differs from traditional software development in many ways, including:\n\n**Frequent code commits**\n\nDevelopers often work independently and infrequently upload their code to a main codebase, causing merge conflicts and other time-consuming issues. With CI/CD, developers push commits throughout the day, ensuring that conflicts are caught early and the codebase remains up to date.\n\n**Reduced risk**\n\nLengthy testing cycles and extensive pre-release planning are hallmarks of traditional software development. This is done to minimize risk but often hinders the ability to find and fix problems. Risk is managed in CI/CD by applying small, incremental changes that are closely monitored and easily reverted.\n\n**Automated and continuous testing**\n\nIn traditional software development, testing is done once development is complete. However, this causes problems, including delayed delivery and costly bug fixes. CI/CD supports automated testing that occurs continuously throughout development, sparked by each code commit. Developers also receive feedback they can take fast action on.\n\n**Automated, repeatable, and frequent deployments**\n\nWith CI/CD, deployments are automated processes that reduce the typical stress and effort associated with big software rollouts. The same deployment process can be repeated across environments, which saves time and reduces errors and inconsistencies.\n\n## Understanding CI/CD fundamentals\n\nCI/CD serves as a framework for building scalable, maintainable delivery processes, so it's critical for DevSecOps teams to firmly grasp its core concepts. A solid understanding of CI/CD principles enables teams to adapt strategies and practices as technology evolves, rather than being tied to legacy approaches. Here are some of the basics.\n\n### What is a CI/CD pipeline?\n\nA [CI/CD pipeline](https://about.gitlab.com/topics/ci-cd/cicd-pipeline/) is a series of steps, such as build, test, and deploy, that automate and streamline the software delivery process. [Each stage serves as a quality gate](https://about.gitlab.com/blog/guide-to-ci-cd-pipelines/), ensuring that only validated code moves forward. Early stages typically handle basic checks like compilation and unit testing, while later stages may include integration testing, performance testing, compliance testing, and staged deployments to various environments.\n\nThe pipeline can be configured to require manual approvals at critical points, such as before deploying to production, while automating routine tasks and providing quick feedback to developers about the health of their changes. This structured approach ensures consistency, reduces human error, and provides a clear audit trail of how code changes move from development to production. Modern pipelines are often implemented as code, allowing them to be version controlled, tested, and maintained just like application code.\n\nThese are other terms associated with CI/CD that are important to know:\n- **Commit:** a code change\n- **Job:** instructions a runner has to execute\n- **Runner:** an agent or server that executes each job individually that can spin up or down as needed\n- **Stages:** a keyword that defines certain job stages, such as \"build\" and \"deploy.\" Jobs of the same stage are executed in parallel. Pipelines are configured using a version-controlled YAML file, `.gitlab-ci.yml`, at the root level of a project.\n\n![CI/CD pipeline diagram](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749673928/Blog/Content%20Images/1690824533476.png)\n\n## Best practices for CI/CD implementation and management\n\nHow successful you are with CI/CD depends greatly on the [best practices](https://about.gitlab.com/blog/how-to-keep-up-with-ci-cd-best-practices/) you implement. \n\n#### CI best practices\n\n* Commit early, commit often.\n* Optimize pipeline stages.\n* Make builds fast and simple.\n* Use failures to improve processes.\n* Make sure the test environment mirrors production.\n\n#### CD best practices\n\n* Start where you are – you can always iterate.\n* Understand the best continuous delivery is done with minimal tools.\n* Track what’s happening so issues and merge requests don't get out of hand.\n* Streamline user acceptance testing and staging with automation.\n* Manage the release pipeline through automation.\n* Implement monitoring for visibility and efficiency. \n\n> ### Bookmark this!\n>\n>Watch our [\"Intro to CI/CD\" webinar](https://www.youtube.com/watch?v=sQ7Nw3o0izc)!\n>\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n\u003Ciframe src=\"https://www.youtube.com/embed/sQ7Nw3o0izc?si=3HpNqIClrc2ncr7Y\" title=\"Intro to CI/CD webinar\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## How to get started with CI/CD\n\nGetting started with CI/CD begins with identifying a simple but representative project to serve as your pilot. Choose a straightforward application with basic testing requirements, as this allows you to focus on learning the pipeline mechanics rather than dealing with complex deployment scenarios. Begin by ensuring your code is in [version control](https://about.gitlab.com/topics/version-control/) and has some [basic automated tests](https://about.gitlab.com/blog/develop-c-unit-testing-with-catch2-junit-and-gitlab-ci/) — even a few unit tests will suffice. The goal is to [create a minimal pipeline](https://about.gitlab.com/blog/how-to-learn-ci-cd-fast/) that you can gradually enhance as your understanding grows.\n\nFor GitLab specifically, the process starts with creating a `.gitlab-ci.yml` file in your project's root directory. This YAML file defines your pipeline stages (basic ones like build, test, and deploy) and jobs. A simple pipeline might look like this: The build stage compiles your code and creates artifacts, the test stage runs your unit tests, and the deploy stage pushes your application to a staging environment. GitLab will automatically detect this file and start running your pipeline whenever changes are pushed to your repository. The platform provides [built-in runners](https://docs.gitlab.com/runner/) to execute your pipeline jobs, though you can also set up your own runners for more control.\n\nAs you become comfortable with the basics, gradually add more sophisticated elements to your pipeline. This might include adding code quality checks, [security scanning](https://docs.gitlab.com/ee/user/application_security/#security-scanning), or automated deployment to production. GitLab's DevSecOps platform includes features like [compliance management](https://about.gitlab.com/blog/meet-regulatory-standards-with-gitlab/), [deployment variables](https://about.gitlab.com/blog/demystifying-ci-cd-variables/), and manual approval gates that you can incorporate as your pipeline matures. Pay attention to pipeline execution time and look for opportunities to run jobs in parallel where possible. Remember to add proper error handling and notifications so team members are promptly alerted of any pipeline failures. Start documenting common issues and solutions as you encounter them — this will become invaluable as your team grows.\n\n> ### Want to learn more about getting started with CI/CD? Register for a [free CI/CD course on GitLab University](https://university.gitlab.com/courses/continuous-integration-and-delivery-ci-cd-with-gitlab).\n\n## Security, compliance, and CI/CD\n\nOne of the greatest advantages of CI/CD is the ability to embed security and compliance checks early and often in the software development lifecycle. In GitLab, teams can use the `.gitlab-ci.yml` configuration to automatically trigger security scans at multiple stages, from initial code commit to production deployment. The platform's container scanning, dependency scanning, and security scanning capabilities ([Dynamic Application Security Testing](https://docs.gitlab.com/ee/user/application_security/dast/) and [Advanced SAST](https://about.gitlab.com/blog/gitlab-advanced-sast-is-now-generally-available/)) can be configured to run automatically with each code change, checking for vulnerabilities, compliance violations, and security misconfigurations. The platform's API enables integration with [external security tools](https://about.gitlab.com/blog/integrate-external-security-scanners-into-your-devsecops-workflow/), while the test coverage features ensure security tests meet required thresholds.\n\nGitLab's security test reports provide detailed information about findings, enabling quick remediation of security issues before they reach production. The Security Dashboard provides a centralized view of vulnerabilities across projects, while [security policies can be enforced](https://about.gitlab.com/blog/how-gitlab-supports-the-nsa-and-cisa-cicd-security-guidance/) through merge request approvals and pipeline gates. In addition, GitLab provides multiple layers of secrets management to protect sensitive information throughout the CI/CD process, audit logs to track access to secrets, and role-based access control (RBAC) to ensure only authorized users can view or modify sensitive configuration data.\n\nGitLab also supports software bill of materials ([SBOM](https://about.gitlab.com/blog/the-ultimate-guide-to-sboms/)) generation, providing a comprehensive inventory of all software components, dependencies, and licenses in an application and enabling teams to quickly identify and respond to vulnerabilities and comply with regulatory mandates.\n\n## CI/CD and the cloud\n\nGitLab's CI/CD platform provides robust integration with major cloud providers including [Amazon Web Services](https://about.gitlab.com/partners/technology-partners/aws/), [Google Cloud Platform](https://about.gitlab.com/blog/provision-group-runners-with-google-cloud-platform-and-gitlab-ci/), and [Microsoft Azure](https://docs.gitlab.com/ee/install/azure/), enabling teams to automate their cloud deployments directly from their pipelines. Through GitLab's cloud integrations, teams can manage cloud resources, deploy applications, and monitor cloud services all within the GitLab interface. The platform's built-in cloud deployment templates and [Auto DevOps](https://docs.gitlab.com/ee/topics/autodevops/) features significantly reduce the complexity of cloud deployments, allowing teams to focus on application development rather than infrastructure management. For organizations that want to automate their IT   infrastructure using GitOps, GitLab has a [Flux CD integration](https://about.gitlab.com/blog/why-did-we-choose-to-integrate-fluxcd-with-gitlab/).\n\nGitLab's cloud capabilities extend beyond basic deployment automation. The platform's [Kubernetes integration](https://about.gitlab.com/blog/kubernetes-overview-operate-cluster-data-on-the-frontend/) enables teams to manage container orchestration across multiple cloud providers, while the [cloud native GitLab installation options](https://about.gitlab.com/topics/ci-cd/cloud-native-continuous-integration/) allow the platform itself to run in cloud environments. Through GitLab's cloud-native features, teams can implement auto-scaling runners that dynamically provision cloud resources for pipeline execution, optimizing costs and performance. The platform's integration with cloud provider security services ensures that security and compliance requirements are met throughout the deployment process.\n\nFor multi-cloud environments, GitLab provides consistent workflows and tooling regardless of the underlying cloud provider. Teams can use GitLab's environment management features to handle different cloud configurations across development, staging, and production environments. The platform's [infrastructure as code](https://docs.gitlab.com/ee/user/infrastructure/iac/) support, particularly its native integration with Terraform, enables teams to version control and automate their cloud infrastructure provisioning. GitLab's monitoring and observability features integrate with cloud provider metrics, providing comprehensive visibility into application and infrastructure health across cloud environments.\n\n## Advanced CI/CD \nCI/CD has evolved far beyond simple build and deploy pipelines. In advanced implementations, CI/CD involves sophisticated orchestration of automated testing, security scanning, infrastructure provisioning, AI, and more. Here are a few advanced CI/CD strategies that can help engineering teams scale their pipelines and troubleshoot issues even as architectural complexity grows.\n\n### Reuse and automation in CI/CD\n\nGitLab is transforming how development teams create and manage CI/CD pipelines with two major innovations: the [CI/CD Catalog](https://about.gitlab.com/blog/ci-cd-catalog-goes-ga-no-more-building-pipelines-from-scratch/) and [CI/CD steps](https://about.gitlab.com/blog/introducing-ci-cd-steps-a-programming-language-for-devsecops-automation/), a new programming language for DevSecOps automation currently in experimental phase. The CI/CD Catalog is a centralized platform where developers can discover, reuse, and contribute CI/CD components. Components function as reusable, single-purpose building blocks that simplify pipeline configuration — similar to Lego pieces for CI/CD workflows. Meanwhile, CI/CD steps support complex workflows by allowing developers to compose inputs and outputs for a CI/CD job. With the CI/CD Catalog and CI/CD steps, DevSecOps teams can easily standardize CI/CD and its components, simplifying the process of developing and maintaining CI/CD pipelines.\n\n> Learn more in our [CI/CD Catalog FAQ](https://about.gitlab.com/blog/faq-gitlab-ci-cd-catalog/) and [CI/CD steps documentation](https://docs.gitlab.com/ee/ci/steps/).\n\n### Troubleshooting pipelines with AI\n\nWhile CI/CD pipelines can and do break, troubleshooting the issue quickly can minimize the impact. GitLab Duo Root Cause Analysis, part of a suite of AI-powered features, removes the guesswork by [determining the root cause for a failed CI/CD pipeline](https://about.gitlab.com/blog/quickly-resolve-broken-ci-cd-pipelines-with-ai/). When a pipeline fails, GitLab provides detailed job logs, error messages, and execution traces that show exactly where and why the failure occurred. Root Cause Analysis then uses AI to suggest a fix.\nWatch GitLab Duo Root Cause Analysis in action:\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n\u003Ciframe src=\"https://www.youtube.com/embed/sTpSLwX5DIs?si=J6-0Bf6PtYjrHX1K\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## How to migrate to GitLab CI/CD\n\nMigrating to the DevSecOps platform and its built-in CI/CD involves a systematic approach of analyzing your existing pipeline configurations, dependencies, and deployment processes to map them to GitLab's equivalent features and syntax. Use these guides to help make the move.\n\n* [How to migrate from Bamboo to GitLab CI/CD](https://about.gitlab.com/blog/migrating-from-bamboo-to-gitlab-cicd/)\n* [Jenkins to GitLab: The ultimate guide to modernizing your CI/CD environment](https://about.gitlab.com/blog/jenkins-gitlab-ultimate-guide-to-modernizing-cicd-environment/)\n* [GitHub to GitLab migration the easy way](https://about.gitlab.com/blog/github-to-gitlab-migration-made-easy/)\n\n## Lessons from leading organizations\n\nThese leading organizations migrated to GitLab and are enjoying the myriad benefits of CI/CD. Read their stories.\n\n- [Lockheed Martin](https://about.gitlab.com/customers/lockheed-martin/)\n- [Indeed](https://about.gitlab.com/blog/how-indeed-transformed-its-ci-platform-with-gitlab/)\n- [CARFAX](https://about.gitlab.com/customers/carfax/)\n- [HackerOne](https://about.gitlab.com/customers/hackerone/)\n- [Betstudios](https://about.gitlab.com/blog/betstudios-cto-on-improving-ci-cd-capabilities-with-gitlab-premium/)\n- [Thales and Carrefour](https://about.gitlab.com/blog/how-carrefour-and-thales-are-evolving-their-ci-cd-platforms/)\n\n## CI/CD tutorials\n\nBecome a CI/CD expert with these easy-to-follow tutorials.\n\n* [Basics of CI: How to run jobs sequentially, in parallel, or out of order](https://about.gitlab.com/blog/basics-of-gitlab-ci-updated/)\n* [How to set up your first GitLab CI/CD component](https://about.gitlab.com/blog/tutorial-how-to-set-up-your-first-gitlab-ci-cd-component/)\n* [Building a GitLab CI/CD pipeline for a monorepo the easy way](https://about.gitlab.com/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way/)\n* [Using child pipelines to continuously deploy to five environments](https://about.gitlab.com/blog/using-child-pipelines-to-continuously-deploy-to-five-environments/)\n* [CI/CD automation: Maximize 'deploy freeze' impact across GitLab groups](https://about.gitlab.com/blog/ci-cd-automation-maximize-deploy-freeze-impact-across-gitlab-groups/)\n* [Refactoring a CI/CD template to a CI/CD component](https://about.gitlab.com/blog/refactoring-a-ci-cd-template-to-a-ci-cd-component/)\n* [Annotate container images with build provenance using Cosign in GitLab CI/CD](https://about.gitlab.com/blog/annotate-container-images-with-build-provenance-using-cosign-in-gitlab-ci-cd)\n\n> #### Get started with GitLab CI/CD. [Sign up for GitLab Ultimate](https://about.gitlab.com/free-trial/devsecops/) and try the AI-powered DevSecOps platform.",[109,9,496,827,694,848],{"slug":3725,"featured":91,"template":698},"ultimate-guide-to-ci-cd-fundamentals-to-advanced-implementation","content:en-us:blog:ultimate-guide-to-ci-cd-fundamentals-to-advanced-implementation.yml","Ultimate Guide To Ci Cd Fundamentals To Advanced Implementation","en-us/blog/ultimate-guide-to-ci-cd-fundamentals-to-advanced-implementation.yml","en-us/blog/ultimate-guide-to-ci-cd-fundamentals-to-advanced-implementation",{"_path":3731,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3732,"content":3738,"config":3743,"_id":3745,"_type":14,"title":3746,"_source":16,"_file":3747,"_stem":3748,"_extension":19},"/en-us/blog/unlocking-agile-excellence-gitlab-epics-for-seamless-portfolio-management",{"title":3733,"description":3734,"ogTitle":3733,"ogDescription":3734,"noIndex":6,"ogImage":3735,"ogUrl":3736,"ogSiteName":686,"ogType":687,"canonicalUrls":3736,"schema":3737},"Unlocking Agile excellence: GitLab Epics for seamless portfolio management","Explore how GitLab's multi-level epics revolutionize Agile portfolio management, offering a structured yet flexible approach for strategic planning and efficient execution.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098713/Blog/Hero%20Images/Blog/Hero%20Images/agile_agile.png_1750098713577.png","https://about.gitlab.com/blog/unlocking-agile-excellence-gitlab-epics-for-seamless-portfolio-management","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Unlocking Agile excellence: GitLab Epics for seamless portfolio management\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Amanda Rueda\"},{\"@type\":\"Person\",\"name\":\"Melissa Ushakov\"}],\n        \"datePublished\": \"2024-02-06\",\n      }",{"title":3733,"description":3734,"authors":3739,"heroImage":3735,"date":3740,"body":3741,"category":1397,"tags":3742},[1394,1632],"2024-02-06","Effective portfolio management is crucial for the success of organizations in the ever-evolving landscape of software development. Placing the right bets, optimally allocating resources, and mitigating risks are all required for effectively executing on your business strategy.\n\nGitLab's portfolio management capabilities offer a structured yet flexible approach for connecting strategy to execution. In this blog post, we'll explore the advantages of GitLab's multi-level epics and their pivotal role in Agile portfolio management.\n\n## Understanding GitLab's multi-level epics\nGitLab's multi-level epics allow organizations to organize their work in a hierarchical structure, providing a clear and detailed view of projects and their interdependencies so that teams can make informed decisions, anticipate potential challenges, and streamline their workflows for enhanced efficiency and successful project delivery. Unlike other tools, GitLab allows nesting epics up to seven layers deep across different groups and projects, enabling efficient cross-functional coordination.\n\n![epics portfolio management - image 1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098728/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750098727863.png)\n\n## Advantages of multi-level epics in portfolio management\n\nThe following are four advantages of multi-level epics in portfolio management.\n\n### 1. Flexible compatibility with Agile frameworks\n\nEpics seamlessly adapt to various scaled Agile frameworks, allowing teams to adjust GitLab to your preferred way of working. Multi-level epics offer a flexible construct to represent different higher-level planning work items with minimal configuration required. This adaptability means teams can efficiently use GitLab for product planning workflows without the need for extensive setup so that they can focus more of their time on strategic planning and less on configuring tools.\n\n### 2. Granular work breakdown\n\nGitLab's multi-level epics enable organizations to break down intricate projects into smaller, manageable components so that teams can identify smaller iterations, allowing for the faster and more frequent delivery of tangible user value. Higher-level epics provide a strategic overview that can span multiple years, while epics closer to deliverables can typically be completed in a handful of sprints. Epics can be broken down into issues and tasks to tie strategic objectives to more tactical deliverables.\n\n![epics portfolio management - image 2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098728/Blog/Content%20Images/Blog/Content%20Images/image4_aHR0cHM6_1750098727864.png)\n\n### 3. Real-time visibility and collaboration\n\nGitLab epics offer real-time visibility into progress, promoting effective team collaboration. GitLab offers unparalleled traceability, with automatic epic progress updates based on downstream DevSecOps activity for connected work items, allowing stakeholders to make informed decisions based on the most up-to-date information, allocate resources effectively, and maintain a proactive approach to managing product timelines.\n\n![epics portfolio management - image 3](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098728/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098727866.png)\n\n### 4. Cross-team planning\n\nMulti-level epics facilitate efficient planning across multiple teams by providing a centralized view of work breakdown and dependencies from teams across your organization, ensuring cohesive collaboration and alignment of efforts. All information for your organization's Agile planning processes and execution of the work lives within a single tool, providing the shared context of how a team's work relates to higher-level strategy.\n\n![epics portfolio management - image 4](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098728/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098727871.png)\n\nGitLab’s portfolio management tools, including multi-level epics, ensure that strategic planning aligns seamlessly with the execution of projects, allowing teams to navigate the complexities of software development with precision, efficiency, and a clear focus on overarching business goals.\n\nReady to harness the full potential of GitLab's multi-level epics and elevate your portfolio management experience? Explore our subscription options on our [pricing page](https://about.gitlab.com/pricing/), and unlock a host of powerful features designed to fuel collaboration, enhance transparency, and propel your projects toward success.",[1399,9,496],{"slug":3744,"featured":91,"template":698},"unlocking-agile-excellence-gitlab-epics-for-seamless-portfolio-management","content:en-us:blog:unlocking-agile-excellence-gitlab-epics-for-seamless-portfolio-management.yml","Unlocking Agile Excellence Gitlab Epics For Seamless Portfolio Management","en-us/blog/unlocking-agile-excellence-gitlab-epics-for-seamless-portfolio-management.yml","en-us/blog/unlocking-agile-excellence-gitlab-epics-for-seamless-portfolio-management",{"_path":3750,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3751,"content":3757,"config":3763,"_id":3765,"_type":14,"title":3766,"_source":16,"_file":3767,"_stem":3768,"_extension":19},"/en-us/blog/use-gitlab-duo-to-build-and-deploy-a-simple-quarkus-native-project",{"title":3752,"description":3753,"ogTitle":3752,"ogDescription":3753,"noIndex":6,"ogImage":3754,"ogUrl":3755,"ogSiteName":686,"ogType":687,"canonicalUrls":3755,"schema":3756},"Use GitLab Duo to build and deploy a simple Quarkus-native project","This tutorial shows how a Java application is compiled to machine code and deployed to a Kubernetes cluster using a CI/CD pipeline. See how AI makes the process faster and more efficient.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749666069/Blog/Hero%20Images/AdobeStock_639935439.jpg","https://about.gitlab.com/blog/use-gitlab-duo-to-build-and-deploy-a-simple-quarkus-native-project","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Use GitLab Duo to build and deploy a simple Quarkus-native project\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Cesar Saavedra\"}],\n        \"datePublished\": \"2024-10-17\",\n      }",{"title":3752,"description":3753,"authors":3758,"heroImage":3754,"date":3759,"body":3760,"category":781,"tags":3761},[1475],"2024-10-17","In [“How to automate software delivery using Quarkus and\nGitLab,”](https://about.gitlab.com/blog/how-to-automate-software-delivery-using-quarkus-and-gitlab/)\nyou learned how to develop and deploy a simple Quarkus-JVM application to a\nKubernetes cluster using [GitLab Auto\nDevOps](https://docs.gitlab.com/ee/topics/autodevops/). Now, you'll learn\nhow to use Quarkus-native to compile a Java application to machine code and\ndeploy it to a Kubernetes cluster using a CI/CD pipeline. Follow our journey\nfrom development to deployment leveraging [GitLab\nDuo](https://about.gitlab.com/gitlab-duo/) as our AI companion, including\nthe specific prompts we used.\n\n\n## What is Quarkus?\n\n\n[Quarkus](https://quarkus.io/), also known as the Supersonic Subatomic Java,\nis an open source, Kubernetes-native Java stack tailored to OpenJDK HotSpot\nand GraalVM. The Quarkus project recently moved to the [Commonhaus\nFoundation](https://www.commonhaus.org/), a nonprofit organization dedicated\nto the sustainability of open source libraries and frameworks that provides\na balanced approach to governance and support.\n\n\n## Prerequisites\n\n\nThis tutorial assumes:\n\n\n- You have a running Kubernetes cluster, e.g. GKE.\n\n- You have access to the Kubernetes cluster from your local laptop via the\n`kubectl` command.\n\n- The cluster is connected to your GitLab project.\n\n- You have [Maven (Version 3.9.6 or later)](https://maven.apache.org/)\ninstalled on your local laptop.\n\n- You have Visual Studio Code installed on your local laptop.\n\n\nIf you’d like to set up a Kubernetes cluster connected to your GitLab\nproject, you can follow the instructions in this\n[tutorial](https://about.gitlab.com/blog/eliminate-risk-with-feature-flags-tutorial/),\nup to but not including the “Creating an instance of MySQL database in your\ncluster via Flux” section (you do not need a database for this tutorial).\n\n\nYou will also need to install an nginx ingress in your Kubernetes cluster.\nHere are two ways to do this:\n\n1. You can follow the instructions in [“Creating and importing\nprojects”](https://about.gitlab.com/blog/eliminate-risk-with-feature-flags-tutorial/#creating-and-importing-projects),\nup to the creation of the variable `KUBE_INGRESS_BASE_DOMAIN`.\n\n2. Or, just create an ingress in your Kubernetes cluster by following the\ninstructions in our [Auto DevOps with GKE\ndocumentation](https://docs.gitlab.com/ee/topics/autodevops/cloud_deployments/auto_devops_with_gke.html#install-ingress).\n\n\n**NOTE:** For this article, we used the first method above to install an\ningress and cert-manager in the Kubernetes cluster.\n\n\n## Creating necessary project files using GitLab Duo Chat\n\n\nWe started our endeavor from VS Code and an empty project called\n`quarkus-native`, which we had previously created in GitLab and had already\ncloned to our local laptop.\n\n\n1. We opened GitLab Duo Chat, within VS Code, and entered the following\nprompt:\n\n\n**_Create a “Hello World” Quarkus application that can be natively\ncompiled_**\n\n\n![hello-world-prompt](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/hello-world-prompt.png)\n\n\nChat replied with the prerequisites and process of what to do to create a\nsimple “Hello World” Quarkus application. At this point, we were after the\ngenerated body of the class `HelloResource.java`:\n\n\n```\n\npackage org.acme;\n\n\nimport javax.ws.rs.GET;\n\nimport javax.ws.rs.Path;\n\nimport javax.ws.rs.Produces;\n\nimport javax.ws.rs.core.MediaType;\n\n\n@Path(\"/hello\")\n\npublic class HelloResource {\n\n    @GET\n    @Produces(MediaType.TEXT_PLAIN)\n    public String hello() {\n        return \"Hello World\";\n    }\n}\n\n```\n\n\n2. We knew that for Quarkus we needed a special Dockerfile, named\n`Dockerfile.native`, as part of the creation of the image for the\napplication executable. We then entered the following prompt in Chat:\n\n\n**_Create the Dockerfile.native file for the sample application above_**\n\n\n![create-dockerfile-prompt](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675941/Blog/Content%20Images/create-dockerfile-prompt.png)\n\n\nChat replied with a very thorough answer about this file, its contents, and\nthe containerization process. At this point, we were just after the\ngenerated body of the file `Dockerfile.native`:\n\n\n```\n\n####\n\n# This Dockerfile is used in order to build a container that runs the\nQuarkus application in native (no JVM) mode\n\n####\n\nFROM registry.access.redhat.com/ubi8/ubi-minimal:8.6\n\nWORKDIR /work/\n\nRUN chown 1001 /work \\\n    && chmod \"g+rwX\" /work \\\n    && chown 1001:root /work\nCOPY --chown=1001:root target/*-runner /work/application\n\n\nEXPOSE 8080\n\nUSER 1001\n\n\nCMD [\"./application\", \"-Dquarkus.http.host=0.0.0.0\"]\n\n```\n\n\n3. Next, we asked Chat to generate the `pom.xml` for this application by\nentering the following prompt:\n\n\n**_Create the pom.xml file for the sample application above_**\n\n\n![create-pom-prompt](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/create-pom-prompt.png)\n\n\nChat provided the content of the `pom.xml` file, an explanation of its\ncontents, and how to use it. At this point, we were after the generated body\nof the file `pom.xml`:\n\n\n```\n\n\u003C?xml version=\"1.0\"?>\n\n\u003Cproject xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0\nhttps://maven.apache.org/xsd/maven-4.0.0.xsd\"\nxmlns=\"http://maven.apache.org/POM/4.0.0\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  \u003CmodelVersion>4.0.0\u003C/modelVersion>\n  \u003CgroupId>org.acme\u003C/groupId>\n  \u003CartifactId>hello-world-quarkus\u003C/artifactId>\n  \u003Cversion>1.0.0-SNAPSHOT\u003C/version>\n  \u003Cproperties>\n    \u003Ccompiler-plugin.version>3.10.1\u003C/compiler-plugin.version>\n    \u003Cmaven.compiler.release>11\u003C/maven.compiler.release>\n    \u003Cproject.build.sourceEncoding>UTF-8\u003C/project.build.sourceEncoding>\n    \u003Cproject.reporting.outputEncoding>UTF-8\u003C/project.reporting.outputEncoding>\n    \u003Cquarkus.platform.artifact-id>quarkus-bom\u003C/quarkus.platform.artifact-id>\n    \u003Cquarkus.platform.group-id>io.quarkus.platform\u003C/quarkus.platform.group-id>\n    \u003Cquarkus.platform.version>2.16.5.Final\u003C/quarkus.platform.version>\n    \u003CskipITs>true\u003C/skipITs>\n    \u003Csurefire-plugin.version>3.0.0-M7\u003C/surefire-plugin.version>\n  \u003C/properties>\n  \u003CdependencyManagement>\n    \u003Cdependencies>\n      \u003Cdependency>\n        \u003CgroupId>${quarkus.platform.group-id}\u003C/groupId>\n        \u003CartifactId>${quarkus.platform.artifact-id}\u003C/artifactId>\n        \u003Cversion>${quarkus.platform.version}\u003C/version>\n        \u003Ctype>pom\u003C/type>\n        \u003Cscope>import\u003C/scope>\n      \u003C/dependency>\n    \u003C/dependencies>\n  \u003C/dependencyManagement>\n  \u003Cdependencies>\n    \u003Cdependency>\n      \u003CgroupId>io.quarkus\u003C/groupId>\n      \u003CartifactId>quarkus-arc\u003C/artifactId>\n    \u003C/dependency>\n    \u003Cdependency>\n      \u003CgroupId>io.quarkus\u003C/groupId>\n      \u003CartifactId>quarkus-resteasy\u003C/artifactId>\n    \u003C/dependency>\n    \u003Cdependency>\n      \u003CgroupId>io.quarkus\u003C/groupId>\n      \u003CartifactId>quarkus-junit5\u003C/artifactId>\n      \u003Cscope>test\u003C/scope>\n    \u003C/dependency>\n    \u003Cdependency>\n      \u003CgroupId>io.rest-assured\u003C/groupId>\n      \u003CartifactId>rest-assured\u003C/artifactId>\n      \u003Cscope>test\u003C/scope>\n    \u003C/dependency>\n  \u003C/dependencies>\n  \u003Cbuild>\n    \u003Cplugins>\n      \u003Cplugin>\n        \u003CgroupId>${quarkus.platform.group-id}\u003C/groupId>\n        \u003CartifactId>quarkus-maven-plugin\u003C/artifactId>\n        \u003Cversion>${quarkus.platform.version}\u003C/version>\n        \u003Cextensions>true\u003C/extensions>\n        \u003Cexecutions>\n          \u003Cexecution>\n            \u003Cgoals>\n              \u003Cgoal>build\u003C/goal>\n              \u003Cgoal>generate-code\u003C/goal>\n              \u003Cgoal>generate-code-tests\u003C/goal>\n            \u003C/goals>\n          \u003C/execution>\n        \u003C/executions>\n      \u003C/plugin>\n      \u003Cplugin>\n        \u003CartifactId>maven-compiler-plugin\u003C/artifactId>\n        \u003Cversion>${compiler-plugin.version}\u003C/version>\n        \u003Cconfiguration>\n          \u003CcompilerArgs>\n            \u003Carg>-parameters\u003C/arg>\n          \u003C/compilerArgs>\n        \u003C/configuration>\n      \u003C/plugin>\n      \u003Cplugin>\n        \u003CartifactId>maven-surefire-plugin\u003C/artifactId>\n        \u003Cversion>${surefire-plugin.version}\u003C/version>\n        \u003Cconfiguration>\n          \u003CsystemPropertyVariables>\n            \u003Cjava.util.logging.manager>org.jboss.logmanager.LogManager\u003C/java.util.logging.manager>\n            \u003Cmaven.home>${maven.home}\u003C/maven.home>\n          \u003C/systemPropertyVariables>\n        \u003C/configuration>\n      \u003C/plugin>\n      \u003Cplugin>\n        \u003CartifactId>maven-failsafe-plugin\u003C/artifactId>\n        \u003Cversion>${surefire-plugin.version}\u003C/version>\n        \u003Cexecutions>\n          \u003Cexecution>\n            \u003Cgoals>\n              \u003Cgoal>integration-test\u003C/goal>\n              \u003Cgoal>verify\u003C/goal>\n            \u003C/goals>\n            \u003Cconfiguration>\n              \u003CsystemPropertyVariables>\n                \u003Cnative.image.path>${project.build.directory}/${project.build.finalName}-runner\u003C/native.image.path>\n                \u003Cjava.util.logging.manager>org.jboss.logmanager.LogManager\u003C/java.util.logging.manager>\n                \u003Cmaven.home>${maven.home}\u003C/maven.home>\n              \u003C/systemPropertyVariables>\n            \u003C/configuration>\n          \u003C/execution>\n        \u003C/executions>\n      \u003C/plugin>\n    \u003C/plugins>\n  \u003C/build>\n  \u003Cprofiles>\n    \u003Cprofile>\n      \u003Cid>native\u003C/id>\n      \u003Cactivation>\n        \u003Cproperty>\n          \u003Cname>native\u003C/name>\n        \u003C/property>\n      \u003C/activation>\n      \u003Cproperties>\n        \u003CskipITs>false\u003C/skipITs>\n        \u003Cquarkus.package.type>native\u003C/quarkus.package.type>\n      \u003C/properties>\n    \u003C/profile>\n  \u003C/profiles>\n\u003C/project>\n\n```\n\n\n4. We then asked Chat to generate the Quarkus test file for this application\nby entering the following prompt:\n\n\n**_Create the content for the Quarkus test for the application above_**\n\n\n![create-quarkus-test-prompt](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/create-quarkus-test-prompt.png)\n\n\nChat returned the body for the Quarkus test, how to use it, and the body of\nthe Java class for the test needed for its native compilation. At this\npoint, we were after the generated bodies of the file\n`HelloResourceTest.java` and `HelloResourceIT.java`.\n\n\nHere is the generated body for `HelloResourceTest.java`:\n\n\n```\n\npackage org.acme;\n\n\nimport io.quarkus.test.junit.QuarkusTest;\n\nimport org.junit.jupiter.api.Test;\n\n\nimport static io.restassured.RestAssured.given;\n\nimport static org.hamcrest.CoreMatchers.is;\n\n\n@QuarkusTest\n\npublic class HelloResourceTest {\n\n    @Test\n    public void testHelloEndpoint() {\n        given()\n          .when().get(\"/hello\")\n          .then()\n             .statusCode(200)\n             .body(is(\"Hello World\"));\n    }\n\n}\n\n```\n\n\nHere is the generated body for `HelloResourceIT.java`:\n\n\n```\n\npackage org.acme;\n\n\nimport io.quarkus.test.junit.QuarkusIntegrationTest;\n\n\n@QuarkusIntegrationTest\n\npublic class HelloResourceIT extends HelloResourceTest {\n    // Execute the same tests but in native mode.\n}\n\n```\n\n\n5. We needed to know how to organize these files in the GitLab project, so\nwe asked about the directory structure for all these files by entering the\nfollowing prompt in Chat:\n\n\n**_Give me the entire directory structure for this project including the\nlocation of each file, e.g. pom.xml, Dockerfile.native,\napplication.properties, HelloResource.java, HelloResourceTest.java, and the\nlocation of the target directory_**\n\n\n![create-dir-struct-prompt](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/create-dir-struct-prompt.png)\n\n\nChat replied with a detailed diagram about the entire directory structure\nfor the project and where all these files should be located as well as a\ndescription of the purpose of each of them. It even mentioned that the\ndirectory `target/` and its contents should not be version controlled since\nit was generated by the build process. Another interesting aspect of the\nreply was the existence of a file called `resources/application.properties`\nin the directory structure.\n\n\n![dir-struct-chat-response](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/dir-struct-chat-response.png)\n\n\nWith all this information in our hands, we were ready to start creating\nthese files in our GitLab project.\n\n\n## Populating our project with the generated content for each file\n\n\nWe created each of the following files in their corresponding location and\ntheir generated content as provided by Chat:\n\n\n- `src/main/java/org/acme/HelloResource.java`\n\n- `resources/application.properties`\n\n- `src/test/java/org/acme/HelloResourceTest.java`\n\n- `src/test/java/org/acme/HelloResourceIT.java`\n\n- `pom.xml`\n\n- `Dockerfile.native`\n\n\n**NOTE:** We considered using GitLab Auto Deploy for this endeavor but later\nrealized that it would not be a supported option. We are mentioning this\nbecause in the video at the end of this tutorial, you will see that we asked\nChat: `How to set the service internalPort to 8080 for auto deploy`. Then we\ncreated a file named `.gitlab/auto-deploy-values.yaml` with the generated\ncontent from Chat. The creation of this file is not necessary for this\ntutorial.\n\n\nBefore we started tackling the pipeline to build, containerize, and deploy\nthe application to our Kubernetes cluster, we decided to generate the\nexecutable locally on our Mac and test the application locally.\n\n\n## Testing the application locally\n\n\nHere is the process we went through to test the application on our local\nmachine.\n\n\n1. To build the application on the local Mac laptop, from a Terminal window,\nwe entered the following command:\n\n\n```\n\nmvn clean package -Pnative\n\n```\n\n\n![first-build](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/first-build.png)\n\n\nThe native compilation failed with the error message:\n\n\n`Cannot find the ‘native-image’ in the GRAALVM_HOME, JAVA_HOME and System\nPATH. Install it using ‘gu install native-image’`\n\n\n2. So, we used our trusty GitLab Duo Chat again and asked it the following:\n\n\n**_The command “mvn clean package -Pnative” is failing with error\n“java.lang.RuntimeException: Cannot find the ‘native-image’ in the\nGRAALVM_HOME, JAVA_HOME and System PATH. Install it using gu install\nnative-image”. I’m using a MacOS Sonoma. How do I fix this error on my\nMac?_**\n\n\n![how-to-fix-build-failure-prompt](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/how-to-fix-build-failure-prompt.png)\n\n\nChat replied with a detailed set of steps on how to install the necessary\nsoftware and set the appropriate environment variables.\n\n\n3. We copied and pasted the following commands from the Chat window to a\nTerminal window:\n\n\n```\n\nbrew install –cask graalvm/tap/graalvm-ce-java17\n\nexport JAVA_HOME=/Library/Java/JavaVIrtualMachines/graalvm-ce-java17-22.3.1\n\nexport GRAALVM_HOME=${JAVA_HOME}\n\nexport PATH=${GRAALVM_HOME}/bin:$PATH\n\nxattr -r -d com.apple.quarantine ${GRAALVM_HOME}/../..\n\ngu install native-image\n\n```\n\n\nThe commands above installed the community edition of GraalVM Version 22.3.1\nthat supported Java 17. We noticed, during the brew install, that the\nversion of the GraalVM being installed was `java17-22.3.1`, so we had to\nupdate the pasted value for `JAVA_HOME` from `graalvm-ce-java17-22.3.0` to\n`graalvm-ce-java17-22.3.1`.\n\n\nWe also had to run the `xattr` command to get the GraalVM, which we had\ndownloaded and installed on our Mac, out of quarantine so that it could run\nlocally. Lastly, we installed the GraalVM native-image.\n\n\n4. At this point, we again, from a Terminal window, entered the following\ncommand to build the application on the local Mac laptop:\n\n\n```\n\nmvn clean package -Pnative\n\n```\n\n\nThis time the compilation was successful and an executable was generated in\nthe `target` directory.\n\n\n![successful-local-compilation](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/successful-local-compilation.png)\n\n\n5. We ran the executable by entering the following commands from a Terminal\nwindow:\n\n\n```\n\ncd target\n\n./quarkus-native-1.0.0-SNAPSHOT-runner “-Dquarkus.http.host=0.0.0.0”\n\n```\n\n\n![executable-local-run](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/executable-local-run.png)\n\n\n6. With the application running, we opened a browser window, and in the URL\nfield, we entered:\n\n\n```\n\nhttp://localhost:8080/hello\n\n```\n\n\n![app-running-locally](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/app-running-locally.png)\n\n\nThe application returned the string `Hello World`, which was displayed in\nthe browser window.\n\n\nAt this point, we committed and pushed all the changes to our GitLab project\nand started working on creating a CI/CD pipeline that would build and deploy\nthe application to a Kubernetes cluster running on the cloud.\n\n\nBut before continuing, we remembered to add, commit, and push a `.gitignore`\nfile to our project that included the path `target/`, since this was the\ndirectory where the executable would be created and we didn’t need to keep\nit - or its contents - under version control.\n\n\n## Creating the pipeline with GitLab Duo Chat\n\n\nNow that we had already successfully tested the application locally on our\nMac, we needed to create the CI/CD pipeline that would compile the\napplication, containerize it, and deploy it to our Kubernetes cluster. We\nwanted to keep the pipeline simple, brief, and have a single environment in\nwhich to deploy it. To this end, the pipeline would not tackle multiple\nenvironments or feature branches, for example.\n\n\n1. To avoid manually creating a pipeline from scratch, we decided to once\nagain leverage Chat. We entered the following prompt\n\n\n**_Create a .gitlab-ci.yml file with 3 stages: build, containerize, and\ndeploy. Each of these stages should have a single job with the same name.\nThe build job should compile the application natively using the -Pnative\nmaven option and the builder image for mandrel jdk-22 for java17 and store\nthe application executable and its Dockerfile as artifacts. The containerize\njob should use docker to build and push the image to the built-in container\nregistry. The deploy job should rollout the containerized application, named\nquarkus-app, to the production environment in the Kubernetes cluster by\ncreating a deployment resource, a service resource and an ingress rule with\nhost ${KUBE_INGRESS_BASE_DOMAIN} and /hello prefix. The deploy job should\nalso include the url for the production environment. When setting the\nKubernetes context, use ${KUBE_CONTEXT}, and for application namespace, use\n${KUBE_NAMESPACE}_**\n\n\n![create-pipeline-prompt](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/create-pipeline-prompt.png)\n\n\nThe prompt above provided some points that we thought would be useful and\nnecessary for a good outcome. The requirements listed by the prompt were:\n\n\n- It specified that the pipeline needed to have three stages: build,\ncontainerize, and deploy.\n\n- Each stage would have a single job.\n\n- The build job should natively compile (not build) the application using\nthe -Pnative option.\n\n- The build job should use the open source software `mandrel` and use the\nversion that would support jdk-22 for Java 17. Remember that these were the\nversions that we tested on our local machine.\n\n- The build job would also need to pass the resulting executable and the\nproject Dockerfile to the next job, i.e. containerize, in the pipeline.\n\n- The containerize job should build a docker image with the executable using\nthe Dockerfile, both of which were passed as artifacts.\n\n- The containerize job should push the image to the GitLab container\nregistry.\n\n- The deploy job should use the image from the GitLab container registry,\nname it `quarkus-app`, and deploy it to the Kubernetes cluster using\ndeployment, service and ingress rule resources.\n\n- The deploy job should use the environment variables\n`${KUBE_INGRESS_BASE_DOMAIN}`, `${KUBE_CONTEXT}`, and `${KUBE_NAMESPACE}`,\nwhich had been defined as group/project variables, accordingly.\n\n\nChat responded with the following `.gitlab-ci.yml` example:\n\n\n```\n\n# Define the stages for the pipeline\n\nstages:\n  - build\n  - containerize\n  - deploy\n\n# Variables section to use GitLab CI/CD variables\n\nvariables:\n  MAVEN_OPTS: \"-Dmaven.repo.local=.m2/repository\"\n  MAVEN_CLI_OPTS: \"--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true\"\n  CONTAINER_IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}\n\n# Cache configuration for Maven dependencies\n\ncache:\n  paths:\n    - .m2/repository\n\n# Build stage: Compile the application natively\n\nbuild:\n  stage: build\n  image:\n    name: quay.io/quarkus/ubi-quarkus-mandrel-builder-image:22.3-java17\n    entrypoint:\n      - \"\"\n  script:\n    - ./mvnw ${MAVEN_CLI_OPTS} clean package -Pnative\n  artifacts:\n    paths:\n      - target/*-runner\n      - src/main/docker/Dockerfile.native-micro\n  # This job runs only on the main branch\n  only:\n      - main\n\n# Containerize stage: Build and push Docker image\n\ncontainerize:\n  stage: containerize\n  image: docker:20.10.16\n  services:\n    - docker:20.10.16-dind\n  variables:\n    DOCKER_TLS_CERTDIR: \"/certs\"\n  before_script:\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n  script:\n    - docker build -f src/main/docker/Dockerfile.native-micro -t ${CONTAINER_IMAGE} .\n    - docker push ${CONTAINER_IMAGE}\n  # This job runs only on the main branch\n  only:\n      - main\n\n# Deploy stage: Deploy to Kubernetes\n\ndeploy:\n  stage: deploy\n  image: \n    name: bitnami/kubectl:latest\n    entrypoint: ['']\n  script:\n    - kubectl config use-context ${KUBE_CONTEXT}\n    - kubectl config set-context --current --namespace=${KUBE_NAMESPACE}\n    - |\n      cat \u003C\u003CEOF | kubectl apply -f -\n      apiVersion: apps/v1\n      kind: Deployment\n      metadata:\n        name: quarkus-app\n      spec:\n        replicas: 1\n        selector:\n          matchLabels:\n            app: quarkus-app\n        template:\n          metadata:\n            labels:\n              app: quarkus-app\n          spec:\n            containers:\n            - name: quarkus-app\n              image: ${CONTAINER_IMAGE}\n              ports:\n              - containerPort: 8080\n      ---\n      apiVersion: v1\n      kind: Service\n      metadata:\n        name: quarkus-app\n      spec:\n        selector:\n          app: quarkus-app\n        ports:\n        - port: 80\n          targetPort: 8080\n      ---\n      apiVersion: networking.k8s.io/v1\n      kind: Ingress\n      metadata:\n        name: quarkus-app\n      spec:\n        rules:\n        - host: ${KUBE_INGRESS_BASE_DOMAIN}\n          http:\n            paths:\n            - path: /hello\n              pathType: Prefix\n              backend:\n                service:\n                  name: quarkus-app\n                  port: \n                    number: 80\n      EOF\n    - echo \"Application deployed to https://${KUBE_INGRESS_BASE_DOMAIN}/hello\"\n  # This job runs only on the main branch\n  only:\n      - main\n```\n\n\n2. There were some things we needed to adjust in the sample `.gitlab-ci.yml`\nfile above before we could commit it to our `main` branch. These are the\nupdates we made to the file:\n\n\n- We deleted all occurrences of `only: -main` because we wanted to keep of\npipeline definition file simple and with no branch-related rules.\n\n- We fixed the name of the file `Dockerfile.native-micro` to\n`Dockerfile.native`.\n\n\n3. At this point, we wanted to ensure that the deployment would be to the\n`production` environment so we asked Chat the following prompt:\n\n\n**_What is the syntax to specify an environment with its url in a\npipeline?_**\n\n\n![how-to-add-env-prompt](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/how-to-add-env-prompt.png)\n\n\nThe response from Chat included an example of how to do this so we used this\ninformation to add the following environment block to our pipeline:\n\n\n```\n  environment:\n       name: production\n       url: http://${KUBE_INGRESS_BASE_DOMAIN}/hello\n```\n\n\n4. The example provided by Chat includes a URL that started with `https` and\nwe modified that to `http` since we didn’t really need a secure connection\nfor this simple application.\n\n\n5. Lastly, we noticed that in the `build` job, there was a script `mvnw`\nthat we didn’t have in our project. So, we asked Chat the following:\n\n\n**_How can I get the mvnw script for Quarkus?_**\n\n\n![how-to-add-mvnw-prompt](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/how-to-add-mvnw-prompt.png)\n\n\nChat responded with the command to execute to bootstrap and create this\nscript. We executed this command from a Terminal window:\n\n\n```\n\nmvn wrapper:wrapper\n\n```\n\n\nWe were now ready to commit all of our changes to the `main` branch and have\nthe pipeline executed. However, on our first attempt, our first pipeline\nfailed at the build job.\n\n\n## Troubleshooting using GitLab Duo Root Cause Analysis\n\n\nOur first attempt at running our brand-new pipeline failed. So, we took\nadvantage of [GitLab Duo Root Cause\nAnalysis](https://about.gitlab.com/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd/),\nwhich looks at the job logs and provides a thorough natural language\nexplanation (with examples) of the root cause of the problem and, most\nimportantly, how to fix it.\n\n\n![build-job-troubleshooting](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/build-job-troubleshooting.png)\n\n\nRoot Cause Analysis recommended we look at the compatibility of the command\nthat was trying to be executed with the image of mandrel used in the build\njob. We were not using any command with the image so we concluded that it\nmust have been the predefined `entrypoint` for the image itself. We needed\nto override this so we asked Chat the following:\n\n\n**_How do I override the entrypoint of an image using gitlab keywords?_**\n\n\n![how-to-override-entrypoint-prompt](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/how-to-override-entrypoint-prompt.png)\n\n\nChat replied with some use case examples of overriding an image entry point.\nWe used that information to update the build job image definition:\n\n\n```\n\nbuild:\n    stage: build\n    image: quay.io/quarkus/ubi-quarkus-mandrel-builder-image:22.3-java17\n    entrypoint:\n        - “”\n```\n\n\nWe committed our changes to the `main` branch, which launched a new instance\nof the pipeline. This time the build job executed successfully but the\npipeline failed at the `containerize` job.\n\n\n## Running a successful pipeline\n\n\nBefore drilling down into the log of the failed `containerize` job, we\ndecided to drill into the log of the successfully completed build job first.\nEverything looked good in the log of the build job with the exception of\nthis warning message at the very end of it:\n\n\n```\n\nWARNING: src/main/docker/Dockerfile.native: no matching files. Ensure that\nthe artifact path is relative to the working directory …\n\n``` \n\n\nWe took notice of this warning and then headed to the log of the failed\n`containerize` job. In it, we saw that the `docker build` command had failed\ndue to a non-existent Dockerfile. We ran Root Cause Analysis on the job and\namong its suggested fixes was for us to verify that the project structure\nmatched the path of the specified `Dockerfile.native` file.\n\n\n![containerize-job-troubleshooting](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/containerize-job-troubleshooting.png)\n\n\nThis information confirmed our suspicion of the misplaced\n`Dockerfile.native` file. Instead of being at the directory\n`src/main/docker` as specified in the pipeline, it was located at the root\ndirectory of the project.\n\n\nSo, we went back to our project and updated every occurrence of the location\nof this file in our `.gitlab-ci.yml` file. We modified the two locations\nwhere this happened, one in the `build` job and one in the `containerize`\njob, as follows:\n\n\n```\n\nsrc/main/docker/Dockerfile.native\n\n```\n\n\nto\n\n\n```\n\nDockerfile.native\n\n```\n\n\nWe committed our updates to the `main` branch and this time our entire\npipeline executed successfully!\n\n\n![pipeline-successful-run](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/pipeline-successful-run.png)\n\n\nOur last step was to check the running application in the `production`\nenvironment in our Kubernetes cluster.\n\n\n## Accessing the deployed application running in cluster\n\n\nOnce the pipeline ran successfully to completion, we drilled in the log file\nfor the `deploy` job. Remember, this job printed the URL of the application\nat the end of its execution. We scrolled down to the bottom of the log and\nclicked on the `https` application link, which opened a browser window\nwarning us that the connection was not private (we disabled `https` for the\nenvironment URL but forgot it for this string). We proceeded past the\nbrowser warning and then the string \"Hello World\" was displaced in the\nbrowser window indicating that the application was up and running in the\nKubernetes cluster.\n\n\nFinally, to double-check our production deployment URL, we headed to the\nproject **Operate > Environments** window, and clicked on the \"Open\" button\nfor it, which immediately opened a browser window with the \"Hello World\"\nmessage.\n\n\n![app-running-on-k8s](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675940/Blog/Content%20Images/app-running-on-k8s.png)\n\n\n## Try it \n\n\nWe created, compiled, built, and deployed a simple Quarkus application to a\nKubernetes cluster using [GitLab Duo](https://about.gitlab.com/gitlab-duo/).\nThis approach allowed us to be more efficient and productive in all the\ntasks that we performed and it helped us streamline our DevSecOps processes.\nWe have shown only a small portion of how GitLab Duo's AI-powered\ncapabilities can help you, namely Chat and Root Cause Analysis. There’s so\nmuch more you can leverage in GitLab Duo to help you create better software\nfaster and more securely.\n\n\nWatch this whole use case in action:\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/xDpycxz3RPY?si=HHZrFt1O_8XoLATf\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\nAll the project assets we used are available\n[here](https://gitlab.com/gitlab-da/use-cases/ai/ai-applications/quarkusn/quarkus-native).\n\n\n> [Try GitLab Duo for free](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/?type=free-trial&toggle=gitlab-duo-pro)\nand get started on exciting projects like this.\n",[717,827,9,3762,719,848,109],"demo",{"slug":3764,"featured":91,"template":698},"use-gitlab-duo-to-build-and-deploy-a-simple-quarkus-native-project","content:en-us:blog:use-gitlab-duo-to-build-and-deploy-a-simple-quarkus-native-project.yml","Use Gitlab Duo To Build And Deploy A Simple Quarkus Native Project","en-us/blog/use-gitlab-duo-to-build-and-deploy-a-simple-quarkus-native-project.yml","en-us/blog/use-gitlab-duo-to-build-and-deploy-a-simple-quarkus-native-project",{"_path":3770,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3771,"content":3777,"config":3783,"_id":3785,"_type":14,"title":3786,"_source":16,"_file":3787,"_stem":3788,"_extension":19},"/en-us/blog/vestiaire-collective-on-moving-to-a-devsecops-platform",{"title":3772,"description":3773,"ogTitle":3772,"ogDescription":3773,"noIndex":6,"ogImage":3774,"ogUrl":3775,"ogSiteName":686,"ogType":687,"canonicalUrls":3775,"schema":3776},"Vestiaire Collective's DevSecOps migration: Wins and insights","Support for container registries and integrations with existing tools were the top reasons for the ecommerce company's migration to GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749670278/Blog/Hero%20Images/fasttrack.jpg","https://about.gitlab.com/blog/vestiaire-collective-on-moving-to-a-devsecops-platform","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Vestiaire Collective VP shares wins, insights, and what's next with DevSecOps migration\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Chandler Gibbons\"}],\n        \"datePublished\": \"2023-01-05\",\n      }",{"title":3778,"description":3773,"authors":3779,"heroImage":3774,"date":3780,"body":3781,"category":972,"tags":3782},"Vestiaire Collective VP shares wins, insights, and what's next with DevSecOps migration",[2636],"2023-01-05","\n[Vestiaire Collective](https://us.vestiairecollective.com/), an online marketplace for second-hand clothing and luxury items, needed a faster and easier-to-use solution for code reviews and running pipelines. In 2018, the company migrated its codebase to GitLab for its speed and flexibility in setting up custom workflows and pipelines for releases. Since making the move, Vestiaire Collective has taken advantage of GitLab’s integrations with other tools — including [Jenkins for CI/CD](https://docs.gitlab.com/ee/integration/jenkins.html), [Jira](https://docs.gitlab.com/ee/integration/jira/) for issue management, and Nexus artifact storage — to improve productivity and simplify complex toolchains. We talked to Sardorbek Pulatov, vice president of engineering at Vestiaire Collective, about what his team has been able to achieve with the GitLab DevSecOps Platform and the lessons learned along the way.\n\n**What were the challenges that led Vestiaire Collective to explore GitLab?**\n\nWhen Vestiaire Collective started with GitLab back in 2018, we wanted to have a fast and in-house version control system with features such as running pipelines. One of the biggest chunks of our code base, the monolith, was on Subversion. We migrated to GitLab for speed and also the better maintainability, and code reviews being much easier. GitLab has also enabled us to set up workflows and pipelines for our releases. And recently we also created our own tool for releases because we have a custom workflow in Jira.\n\nNow we have not just engineers in GitLab, but also data engineers and data scientists. So, for example, data scientists manage their releases through their repositories in GitLab. They’re actually quite advanced in using GitLab, the data scientist teams. So they use everything new released by GitLab.\n\n**Since moving to a single platform for DevSecOps, what are the biggest benefits you’ve noticed? How has GitLab helped Vestiaire Collective simplify complicated toolchains?**\n\nWhen GitLab released support for container registries and npm, it was such a relief for us because we were using Amazon Elastic Container Registry (ECR) and it was slow because it was in a different location — we deploy in Ireland but our team is spread across Europe and the United States. We also tried to use our own setup with Nexus and support it ourselves, meaning if there was a vulnerability we would need to update it and maintain it separately. Even if that’s only required once every six months, it still takes time. You still need to plan the upgrade. But with GitLab, our problem was solved. Now developers have [a registry for containers inside GitLab](https://docs.gitlab.com/ee/user/packages/container_registry/) so they can easily push new releases of their services.\n\nThe fact that GitLab integrates with the other tools we are using has also been a huge benefit. We use Jira for project management, and thanks to GitLab’s Jira integration, whenever a developer pushes a commit in GitLab it’s fully visible in Jira. And now, with our custom integration, the releases are also synced, so when you create a release in GitLab, it creates a release with the same ticket in Jira.\n\nAs a next step, personally, I would love us to be able to migrate entirely into GitLab for project management, using GitLab [issues](https://docs.gitlab.com/ee/user/project/issues/index.html) and [epics](https://docs.gitlab.com/ee/user/group/epics/). We’re not there yet, but GitLab provides almost all the functionality needed for developers. Tracking everything in GitLab would make it much easier to reference the issues in code reviews. Now, when you create a ticket in Jira, you need to create a branch in GitLab with the Jira ticket number, and then, when you push a commit, you also need to remember the ticket number. But once everything is in GitLab, we’ll be able to just push a commit to a merge request. GitLab already gives us so much transparency into what we are doing. That would be even greater if everyone was using GitLab issues and epics.\n\n**What has the response from your team been like?**\n\nThere have been no complaints about stability or performance, and the performance is improving release by release! GitLab became very fast with [version 15](/releases/2022/05/22/gitlab-15-0-released/) — I can feel and see the performance boost. People are happy. People have been quiet, and when engineers are not complaining, that means that the tool is quite good. \n\n**For companies that are just getting started with GitLab, what advice would you give them on where to start?**\n\nI’d recommend starting with smaller projects, setting up all the steps needed for your pipeline, and trying to use features of GitLab such as issues and epics. In our case, we started with a larger project from our Product Information Management service team — the project’s repository had three services and we needed to run different pipelines for different changes. And even in our case, GitLab was quite flexible. We could say, “Okay, if a commit message has this specific word, then run these steps. If it has this word, run these other steps.”\n\nWhat we learned from that experience was that first it’s valuable to understand what you need to run as a pipeline. What comes to mind first is tests and probably deployment into an environment. Then we need to monitor the performance and see if we need to pass our caches in between the pipelines to speed up the deployment, or in the case of Node.js, do not download [npm packages](https://docs.gitlab.com/ee/user/packages/npm_registry/) in every change or merge request or branch. Just cache it once in the first run. Then you can optimize step by step. So that’s what I mean by starting small.\n\n**What are you most looking forward to doing with GitLab in the future?**\n\nI love this question. First, I would like to point out that GitLab surprises me with each release. Personally, I am looking forward to using more automation tools for QA engineers, as well as auto pipelines and integrations with the latest automation frameworks.\n\nWe recently moved away from Sentry for error tracking, so I’m also interested in exploring doing [error tracking in GitLab](https://docs.gitlab.com/ee/operations/error_tracking.html). And, I’m interested in seeing how we might be able to use [feature flags in GitLab](https://docs.gitlab.com/ee/operations/feature_flags.html). We’re currently using LaunchDarkly for A/B testing, but if GitLab can even match half of that functionality, it would be great to bring everything together into one platform.\n\nFinally, we’re also looking into how we can make our GitLab implementation even better and more stable, so we want to deploy it into [a Kubernetes cluster](https://docs.gitlab.com/ee/user/clusters/agent/). Currently, it’s just deployed into EC2s, so that would be our next big step for GitLab.\n\nPhoto by [Mathew Schwartz](https://unsplash.com/@cadop?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com)\n",[9,974,1039,825,826],{"slug":3784,"featured":6,"template":698},"vestiaire-collective-on-moving-to-a-devsecops-platform","content:en-us:blog:vestiaire-collective-on-moving-to-a-devsecops-platform.yml","Vestiaire Collective On Moving To A Devsecops Platform","en-us/blog/vestiaire-collective-on-moving-to-a-devsecops-platform.yml","en-us/blog/vestiaire-collective-on-moving-to-a-devsecops-platform",{"_path":3790,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3791,"content":3797,"config":3802,"_id":3804,"_type":14,"title":3805,"_source":16,"_file":3806,"_stem":3807,"_extension":19},"/en-us/blog/vulnerability-risk-prioritization-made-simple-with-gitlab",{"title":3792,"description":3793,"ogTitle":3792,"ogDescription":3793,"noIndex":6,"ogImage":3794,"ogUrl":3795,"ogSiteName":686,"ogType":687,"canonicalUrls":3795,"schema":3796},"Vulnerability risk prioritization made simple with GitLab","GitLab provides detailed vulnerability risk data to assess the potential impact of detected vulnerabilities. Learn how this enables teams to effectively prioritize remediation efforts.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674528/Blog/Hero%20Images/blog-image-template-1800x945__5_.png","https://about.gitlab.com/blog/vulnerability-risk-prioritization-made-simple-with-gitlab","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Vulnerability risk prioritization made simple with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Fernando Diaz\"}],\n        \"datePublished\": \"2025-03-12\",\n      }",{"title":3792,"description":3793,"authors":3798,"heroImage":3794,"date":3799,"body":3800,"category":694,"tags":3801},[1533],"2025-03-12","Development and security teams are often overwhelmed by the number of\nvulnerabilities they need to remediate. Many organizations remediate [less\nthan 16%](https://arxiv.org/pdf/2302.14172) of their known vulnerabilities\nmonthly. Vulnerability management teams face a constant challenge: which\nsecurity flaws deserve immediate attention? Three key frameworks help answer\nthis question: Common Vulnerability Scoring System\n([CVSS](https://nvd.nist.gov/vuln-metrics/cvss)), Known Exploited\nVulnerabilities\n([KEV](https://www.cisa.gov/known-exploited-vulnerabilities-catalog)), and\nExploit Prediction Scoring System ([EPSS](https://www.first.org/epss/)). The\n[GitLab 17.9\nrelease](https://about.gitlab.com/releases/2025/02/20/gitlab-17-9-released/)\nadds support for these frameworks. In this article, you'll learn how to use\nthese frameworks within GitLab to efficiently prioritize risk across your\ndependency and container image vulnerabilities using this data. \n\n\n![Vulnerability risk assessment\ndata](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674763/Blog/Content%20Images/vulnerability_data.png)\n\n\n\u003Ccenter>\u003Ci>Vulnerability risk assessment data\u003C/i>\u003C/center>\n\n\n## CVSS\n\n\nCVSS provides a standardized method for rating the severity of security\nvulnerabilities. Scores range from 0 to 10, with higher values indicating\ngreater severity.\n\n\nCVSS evaluates vulnerabilities across three dimension groups:\n\n\n* Base metrics: intrinsic qualities that don't change over time (attack\ncomplexity, privileges   required)  \n\n* Temporal metrics: factors that evolve (exploit maturity, remediation\nlevel)  \n\n* Environmental metrics: organization-specific impact considerations\n\n\nCVSS offers a consistent severity baseline and common language for security\nteams. Its comprehensive scoring methodology considers multiple aspects of a\nvulnerability's technical impact.\n\n\n## KEV\n\n\nThe Cybersecurity and Infrastructure Security Agency (CISA) maintains the\nKEV catalog, which identifies vulnerabilities actively exploited in the\nwild.\n\n\nUnlike academic severity scores, KEV focuses on real-world threat\nintelligence. Each entry includes:\n\n\n* CVE identifier  \n\n* Vulnerability name  \n\n* Action required  \n\n* Due date for remediation (for federal agencies)\n\n\nKEV provides actionable intelligence based on observed threat actor\nbehavior. It cuts through scoring complexity with a binary signal: \"This\nvulnerability is being actively exploited right now.\"\n\n\n## EPSS\n\n\nThe EPSS uses machine learning to predict the likelihood a vulnerability\nwill be exploited in the next 30 days. Scores range from 0 to 1 (or\n0%-100%), representing probability.\n\n\nEPSS analyzes hundreds of factors, including:\n\n* Technical characteristics  \n\n* Social media mentions  \n\n* Exploit availability  \n\n* Vulnerability age\n\n\nEPSS brings risk-based prioritization to vulnerability management. Rather\nthan focusing solely on technical severity, it helps teams understand which\nvulnerabilities attackers are most likely to target.\n\n\n## Combining the frameworks for effective prioritization\n\n\nEach framework serves a unique purpose:\n\n\n* CVSS indicates how severe a vulnerability is technically.  \n\n* KEV indicates which vulnerabilities are actively being exploited. \n\n* EPSS indicates which vulnerabilities are likely to be exploited soon.\n\n\nAn effective prioritization strategy leverages all three:\n\n\n1. Start with KEV-listed vulnerabilities as immediate priorities.  \n\n2. Use EPSS to identify high-probability threats not yet on KEV.  \n\n3. Consider CVSS for understanding technical impact.\n\n\nBy combining these complementary frameworks, security teams can focus\nlimited resources on the vulnerabilities that pose the greatest actual risk\nto their organizations. You can get started with prioritizing\nvulnerabilities with GitLab by:\n\n\n1. Adding security scanners to your pipeline  \n\n2. Viewing vulnerability insights  \n\n3. Setting the vulnerability status based metrics\n\n\nWatch this video to learn more:\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/7-dWwoKfCHw?si=iC73JCRsxPUEWKf-\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n### Adding security scanners to your pipeline\n\n\nGitLab provides built-in security scanning tools through its templates that\ncan be integrated directly into your CI/CD pipeline. GitLab offers several\nsecurity scanners that address different aspects of your application\nsecurity:\n\n\n* **[Static Application Security Testing\n(SAST)](https://docs.gitlab.com/user/application_security/sast/):** Analyzes\nyour source code for known vulnerabilities  \n\n* **[Dynamic Application Security Testing\n(DAST)](https://docs.gitlab.com/user/application_security/dast/):** Tests\nyour running application for vulnerabilities  \n\n* **[Dependency\nScanning](https://docs.gitlab.com/user/application_security/dependency_scanning/):**\nChecks your dependencies for known vulnerabilities  \n\n* **[Container\nScanning](https://docs.gitlab.com/user/application_security/container_scanning/):**\nIdentifies vulnerabilities in container images  \n\n* **[Secret\nDetection](https://docs.gitlab.com/user/application_security/secret_detection/):**\nFinds secrets and credentials accidentally committed to your repository  \n\n* **[Infrastructure as Code\nScanning](https://docs.gitlab.com/user/application_security/iac_scanning/):**\nDetects security issues in IaC files  \n\n* **[Coverage-guided\nFuzzing](https://docs.gitlab.com/user/application_security/coverage_fuzzing/):**\nSends random inputs to an instrumented version of your application in an\neffort to detect bugs  \n\n* **[Web API\nFuzzing](https://docs.gitlab.com/user/application_security/api_fuzzing/):**\nSets operation parameters to unexpected values in an effort to cause\nunexpected behavior and errors in the API backend\n\n\nTo add them to your pipeline, simply add the appropriate templates to\n`.gitlab-ci.yml` file. For example, adding SAST and Dependency Scanning to\nyour pipeline is as simple as:\n\n\n```yaml  \n\ninclude:  \n  - template: Security/SAST.gitlab-ci.yml  \n  - template: Security/Dependency-Scanning.gitlab-ci.yml\n\nstages:  \n  - test  \n```\n\n\nOnce you commit the above changes, security scanners will begin to run.\nThese scanners can be further configured to meet the needs of your\norganization. To learn more about our various scanners, see the [GitLab\napplication security\ndocumentation](https://docs.gitlab.com/user/application_security/).\n\n\n**Note:** EPSS and KEV metrics are only provided for\n[dependency](https://docs.gitlab.com/user/application_security/dependency_scanning/)\nand [container\nimage](https://docs.gitlab.com/user/application_security/container_scanning/)\nvulnerabilities.\n\n\n### Viewing vulnerability insights\n\n\nOnce a pipeline with your security scanners is run on the default branch,\nyou can access the vulnerability report. The vulnerability report provides a\nconsolidated view of all security vulnerabilities detected across your\nproject by GitLab's security scanners. You can access it from your project\nby going to the side-tab and selecting **Secure > Vulnerability Report**.\n\n\n![Vulnerability report grouped by\ntool](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674763/Blog/Content%20Images/vulnerability_report__1_.png)\n\n\n\u003Ccenter>\u003Ci>Vulnerability report grouped by tool\u003C/i>\u003C/center>\n\n\u003Cbr>\u003C/br>\n\n\nFrom the vulnerability report, select a vulnerability to see its insights\npage, which includes the severity, EPSS, KEV, and CVSS along with the\nfollowing:\n\n\n* description  \n\n* when it was detected  \n\n* current status  \n\n* available actions  \n\n* linked issues  \n\n* actions log  \n\n* filename and line number of the vulnerability (if available)\n\n\nThis data can be used to effectively triage, remediate, or mitigate the\nvulnerability.\n\n\n__Note:__ From the insights page, you can also leverage GitLab Duo’s AI\ncapabilities to\n[explain](https://docs.gitlab.com/user/application_security/vulnerabilities/#vulnerability-explanation)\nand\n[auto-resolve](https://docs.gitlab.com/user/application_security/vulnerabilities/#vulnerability-resolution)\na vulnerability.\n\n\n### Setting the vulnerability status-based metrics\n\n\nAfter examining the provided data, we can go ahead and change the status of\nour vulnerability by clicking the **Change status** button:  \n\n\n![Change vulnerability status from insights\npage](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674764/Blog/Content%20Images/change_status.png)\n\n\n\u003Ccenter>\u003Ci>Change vulnerability status from insights page\u003C/i>\u003C/center>\n\n\u003Cbr>\u003C/br>\n\n\nThen we'll see a popup that will allow you to change the status of a\nvulnerability:\n\n\n![Change vulnerability status\noption](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749674763/Blog/Content%20Images/change_status_2.png)\n\n\n\u003Ccenter>\u003Ci>Change vulnerability status option\u003C/i>\u003C/center>\n\n\n\u003Cbr>\u003C/br>\n\n\nWhen you dismiss a vulnerability you can choose one of the following reasons\nand optionally provide a comment:\n\n\n* **Acceptable risk:** The vulnerability is known, and has not been\nremediated or mitigated, but is considered to be an acceptable business\nrisk.  \n\n* **False positive:** An error in reporting in which a test result\nincorrectly indicates the presence of a vulnerability in a system when the\nvulnerability is not present.  \n\n* **Mitigating control:** The vulnerability’s risk is mitigated by a\nmanagement, operational, or technical control (that is, safeguard or\ncountermeasure) employed by an organization that provides equivalent or\ncomparable protection for an information system.  \n\n* **Used in tests:** The finding is not a vulnerability because it is part\nof a test or is test data.  \n\n* **Not applicable:** The vulnerability is known, and has not been\nremediated or mitigated, but is considered to be in a part of the\napplication that will not be updated.\n\n\nAnd there you have it, quick and easy vulnerability risk prioritization with\nGitLab!\n\n\n> Get started today with [a free trial of GitLab\nUltimate](https://about.gitlab.com/pricing/ultimate/)!\n\n\n## Learn more\n\n\nTo learn more about GitLab security and governance features and how we can\nhelp enhance your security posture, check out the following resources:\n\n\n* [GitLab Risk Assessment\nData](https://docs.gitlab.com/user/application_security/vulnerabilities/risk_assessment_data/)   \n\n* [GitLab Security and Compliance\nSolutions](https://about.gitlab.com/solutions/security-compliance/)  \n\n* [GitLab Application Security\ndocumentation](https://docs.gitlab.com/ee/user/application_security/)  \n\n* [GitLab Risk Assessment Data\nepic](https://gitlab.com/groups/gitlab-org/-/epics/11544)\n",[827,694,9],{"slug":3803,"featured":91,"template":698},"vulnerability-risk-prioritization-made-simple-with-gitlab","content:en-us:blog:vulnerability-risk-prioritization-made-simple-with-gitlab.yml","Vulnerability Risk Prioritization Made Simple With Gitlab","en-us/blog/vulnerability-risk-prioritization-made-simple-with-gitlab.yml","en-us/blog/vulnerability-risk-prioritization-made-simple-with-gitlab",{"_path":3809,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3810,"content":3816,"config":3821,"_id":3823,"_type":14,"title":3824,"_source":16,"_file":3825,"_stem":3826,"_extension":19},"/en-us/blog/what-is-a-large-language-model-llm",{"title":3811,"description":3812,"ogTitle":3811,"ogDescription":3812,"noIndex":6,"ogImage":3813,"ogUrl":3814,"ogSiteName":686,"ogType":687,"canonicalUrls":3814,"schema":3815},"What is a large language model (LLM)?","Learn how large language models work, their applications, and their impact on the DevSecOps world.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749660057/Blog/Hero%20Images/LLM.jpg","https://about.gitlab.com/blog/what-is-a-large-language-model-llm","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"What is a large language model (LLM)?\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"}],\n        \"datePublished\": \"2025-05-29\",\n      }",{"title":3811,"description":3812,"authors":3817,"heroImage":3813,"date":3818,"body":3819,"category":781,"tags":3820},[1612],"2025-05-29","Large language models (LLMs) are revolutionizing DevOps and DevSecOps approaches by simplifying complex tasks, such as code creation, log analysis, and vulnerability detection.\n\nIn this article, you will learn how LLMs work, their practical applications, and the main challenges to overcome in order to fully harness their potential.\n\n## What is an LLM?\n\nLLMs are artificial intelligence (AI) systems that can process and generate text autonomously. They are trained by analyzing vast amounts of data from a variety of sources, enabling them to master the linguistic structures, contextual relationships, and nuances of language.\n\nLLMs are a major breakthrough in the field of AI. Their ability to process, generate, and interpret text relies on sophisticated machine learning and natural language processing (NLP) techniques. These systems do not just process individual words; they analyze complex sequences to capture the overall meaning, subtle contexts, and linguistic nuances.\n\n## How do LLMs work?\n\nTo better understand how they work, let's explore some of the key features of large language models.\n\n### Supervised and unsupervised learning\n\nLLMs are trained using two complementary approaches: supervised learning and unsupervised learning. These two approaches to machine learning maximize their ability to analyze and generate text.\n\n* **Supervised learning** relies on labeled data, where each input is associated with an expected output. The model learns to associate these inputs with the correct outputs by adjusting its internal parameters to reduce prediction errors. Through this approach, the model acquires precise knowledge about specific tasks, such as text classification or named entity recognition.\n\n* **Unsupervised learning (or machine learning)**, on the other hand, does not require labeled data. The model explores large volumes of text to discover hidden structures and identify semantic relationships. The model is therefore able to learn recurring patterns, implicit grammatical rules in the text, and contextualization of sentences and concepts. This method allows LLMs to be trained on large corpora of data, greatly accelerating their progress without direct human action.\n\nBy combining these two approaches, large language models gain the advantages of both precise, human-guided learning and unlimited autonomous exploration. This complementarity allows them to develop rapidly, while continuously improving their ability to understand and generate text coherently and contextually.\n\n### Learning based on a large volume of data\n\nLLMs are trained on billions of sentences from a variety of sources, such as news articles, online forums, technical documentation, scientific studies, and more. This variety of sources allows them to acquire a broad and nuanced understanding of natural language, ranging from everyday expressions to specialized terminology.\n\nThe richness of the data used is a key factor in LLMs' performance. Each source brings different writing styles, cultural contexts, and levels of technicality. \n\nFor example:\n\n* **News articles** to master informative and factual language \n* **Online forums** to understand specialized communities' informal conversations and technical language  \n* **Technical documentation and scientific studies** to assimilate complex concepts and specific terminology, particularly in areas such as DevOps and DevSecOps\n\nThis diversity of content allows LLMs to recognize complex linguistic structures, interpret sentences in different contexts, and adapt to highly technical domains. In DevSecOps, this means understanding commands, configurations, security protocols, and even concepts related to the development and maintenance of computer systems.\n\nWith this large-scale training, LLMs can accurately answer complex questions, write technical documentation, or identify vulnerabilities in computer systems.\n\n### Neural network architecture and \"deep learning\"\n\nLLMs are based on advanced neural network architectures. These networks are specially designed to process large sequences of text while maintaining an accurate understanding of the context. This deep learning-based training is a major asset in the field of NLP.\n\nThe best-known of these structures is the architecture of sequence-to-sequence models (transformers). This architecture has revolutionized NLP with its ability to simultaneously analyze all parts of a text, unlike sequential approaches that process words one by one.\n\nSequence-to-sequence models excel at processing long texts. For example, in a conversation or a detailed technical document, they are able to link distant information in the text to produce precise and well-reasoned answers. This context management is essential in a DevSecOps approach, where instructions can be complex and spread over multiple lines of code or configuration steps.\n\n### Predictive text generation\n\nWhen the user submits a text, query, or question, an LLM uses its predictive ability to generate the most likely sequence, based on the context provided.\n\nThe model analyzes each word, studies grammatical and semantic relationships, and then selects the most suitable terms to produce a coherent and informative text. This approach makes it possible to generate precise, detailed responses adapted to the expected tone.\n\nIn DevSecOps environments, this capability becomes particularly useful for:\n\n* **Coding assistance:** generation of code blocks or scripts adapted to specific configurations\n* **Technical problem solving:** proposing solutions based on descriptions of bugs or errors\n* **Drafting technical documentation:** automatic creation of guides, manuals, or instructions\n\nPredictive text generation thus makes it possible to automate many repetitive tasks and speed up technical teams' work.\n\n## Applications of large language models in a DevSecOps approach\n\nWith the rise of automation, LLMs have become indispensable allies for technical teams. Their ability to understand and generate text contextually enables them to effectively operate in complex environments such as [DevSecOps](https://about.gitlab.com/topics/devsecops/).\n\nWith their analytical power and ability to adapt to specific needs, these models offer tailored solutions to streamline processes and lighten technical teams' workload.\n\nDevelopment teams can leverage LLMs to automatically transform functional specifications into source code. \n\nWith this capability, they can perform the following actions:\n- generate complex automation scripts\n- create CI/CD pipelines tailored to specific business processes\n- produce customized security patches\n- generate code explanation and create documentation\n- refactor code by improving code structure and readability without changing functionality\n- generate tests\n\nBy relying on LLMs, teams are able to accelerate the development of their software while reducing the risk of human error.\n\n### Improved documentation and knowledge sharing\n\nThese powerful tools make it easy to create customized user manuals, API descriptions, and tutorials that are perfectly tailored to each user's level of expertise. By leveraging existing knowledge bases, LLMs create contextual answers to frequently asked questions. This enhances knowledge sharing within teams, speeds up onboarding of new members, and helps centralize best practices.\n\n### Incident management and troubleshooting\nDuring an incident, LLMs play a crucial role in analyzing logs and [trace files](https://docs.gitlab.com/ee/development/tracing.html) in real time. Thanks to their ability to cross-reference information from multiple sources, they identify anomalies and propose solutions based on similar past incidents. This approach significantly reduces diagnosis time. In addition, LLMs can automate the creation of detailed incident reports and recommend specific corrective actions.\n\n### Creating and improving CI/CD pipelines\n\nLLMs are revolutionizing the configuration of [CI/CD pipelines](https://about.gitlab.com/topics/ci-cd/cicd-pipeline/). They can not only help create pipelines, but also automate this process and suggest optimal configurations based on industry standards. By adapting workflows to your specific needs, they ensure perfect consistency between different development environments. Automated testing is enhanced by relevant suggestions, limiting the risk of failure. LLMs also continuously monitor the efficiency of pipelines and adjust processes to ensure smooth and uninterrupted rollout.\n\n### Security and compliance\n\nIn a DevSecOps environment, large language models become valuable allies for security and compliance. They parse the source code for potential vulnerabilities and generate detailed patch recommendations. LLMs can also monitor the application of security standards in real time, produce comprehensive compliance reports, and automate the application of security patches as soon as a vulnerability is identified. This automation enhances overall security and ensures consistent compliance with legal and industry requirements.\n\n## What are the benefits of large language models?\n\nLLMs are radically reshaping DevOps and DevSecOps approaches, bringing substantial improvements in productivity, security, and software quality. By integrating with existing workflows, LLMs are disrupting traditional approaches by automating complex tasks and providing innovative solutions.\n\n### Improved productivity and efficiency\n\nLLMs play a central role in improving technical teams' productivity and efficiency. By automating a wide range of repetitive tasks, they free development teams from routine operations, allowing them to focus on strategic activities with higher added value.\n\nIn addition, LLMs act as intelligent technical assistants capable of instantly providing relevant code snippets, tailored to the specific context of each project. In this way, they significantly reduce research time by offering ready-to-use solutions to assist teams in their work. This targeted assistance speeds up problem solving and reduces disruptions in workflows.\nAs a result, productivity increases and projects move forward more quickly. Technical teams can take on more tasks without compromising the quality of deliverables.\n\n### Improved code quality and security\n\nThe use of large language models in software development is a major lever for improving both code quality and application security. With their advanced analytical capabilities, LLMs can scan source code line by line and instantly detect syntax errors, logical inconsistencies, and potential vulnerabilities. Their ability to recognize defective code allows them to recommend appropriate fixes that comply with industry best practices.\n\nLLMs also play a key preventive role. They excel at identifying complex security flaws that are often difficult for humans to detect. By analyzing dependencies, they can flag obsolete or vulnerable libraries and recommend more secure, up-to-date versions. This approach contributes to maintaining a secure environment that complies with current security standards.\n\nBeyond fixing existing errors, LLMs offer improvements by suggesting optimized coding practices and project structures. They can generate code that meets the most advanced security standards from the earliest stages of development.\n\n### Accelerating development lifecycles\n\nLarge language models play a key role in accelerating software development lifecycles by automating key tasks that would otherwise tie up valuable human resources. Complex and repetitive tasks, such as writing functions, creating unit tests, or implementing standard components, are automated in a matter of moments.\n\nLLMs also speed up the validation phase with their ability to suggest complete and appropriate test cases. They ensure broader test coverage in less time, reducing the risk of errors and enabling early detection of anomalies. This preventive approach shortens the correction cycle and limits delays related to code quality issues.\n\nBy simplifying technical tasks and providing fast and tailored solutions, large language models enable businesses to respond to market demands in a more agile way. This acceleration of the development lifecycle results in more frequent updates, faster iterations, and a better ability to adapt products to users' changing needs.\n\nDevelopment lifecycles are becoming shorter, providing a critical strategic advantage in an increasingly demanding technology landscape.\n\n## What are the challenges of using LLMs?\n\nDespite their many benefits, large language models have certain limitations that require careful management. Their effectiveness depends heavily on the quality of the data used during their training and regular updates to their knowledge bases. In addition, issues related to algorithmic bias, data security, and privacy can arise, exposing companies to operational and legal risks. Rigorous human oversight remains essential in order to ensure the reliability of results, maintain regulatory compliance, and prevent critical errors.\n\n### Data privacy and security\n\nTraining LLMs relies on large volumes of data, often from diverse sources, raising questions about the protection of confidential information. Sensitive data shared with cloud platforms can therefore be exposed to potential breaches. This is of particular concern to companies operating in regulated sectors. \n\nIn Europe, where strict regulations like GDPR govern data management, many companies are reluctant to transfer their information to external services. Regulatory requirements, coupled with the fear of unauthorized exploitation of sensitive data, have led some companies to opt for self-hosted solutions to maintain complete control over their systems.\n\nProviders like GitLab have put in place robust security guarantees, such as intentional non-retention of personal data and end-to-end encryption. However, this may not be enough for the most demanding customers, who prefer complete control of their environments. Implementing hybrid or on-premises solutions then becomes a strategic necessity to meet the security requirements of certain companies.\n\nLearn more about GitLab Duo Self-Hosted by clicking on the image below to access our product tour.\n\n[![GitLab Duo Self-Hosted tour](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749673815/Blog/Content%20Images/Screenshot_2025-05-29_at_8.29.30%C3%A2__AM.png)](https://gitlab.navattic.com/gitlab-duo-self-hosted)\n\n### Accuracy and reliability\n\nAlthough large language models are capable of producing impressive results, their performance is not infallible. They can produce incorrect, incomplete, or inconsistent answers. This inaccuracy becomes particularly problematic in the context of critical tasks such as generating security code or analyzing sensitive data.\n\nIn addition, LLMs operate on the basis of probabilistic models, which means that they do not truly \"understand\" the content they process, but produce predictions based on statistical probabilities. This can lead to technically incorrect or even dangerous recommendations when used without human validation.\n\nTo avoid these pitfalls, it is essential to maintain constant oversight and establish rigorous validation processes. The results provided by LLMs must always be reviewed by humans before being integrated into critical systems.\n\nA strategy of regular model updates, combined with proactive human oversight, can reduce errors and gradually improve the reliability of results.\n\n## How GitLab uses LLMs for GitLab Duo features\n\n[GitLab Duo](https://about.gitlab.com/gitlab-duo/) harnesses the power of large language models to transform DevSecOps processes by integrating AI-powered capabilities throughout the software development lifecycle. This approach aims to improve productivity, strengthen security, and automate complex tasks so that development teams can focus on high added-value tasks.\n\n### AI-assisted software development\n\nGitLab Duo provides continuous support throughout the software development lifecycle with real-time recommendations. Development teams can automatically generate unit tests, get detailed explanations of complex code segments, and benefit from suggestions to improve the quality of their code.\n\n### Proactive CI/CD failure analysis\n\nOne of the key features of GitLab Duo is its assistance in analyzing CI/CD job failures. With LLM and AI, teams are able to quickly identify sources of errors in their continuous integration and deployment pipelines. \n\n### Enhanced code security\n\nGitLab Duo incorporates AI-based security features. The system detects vulnerabilities in the source code and proposes detailed patches to reduce the risks. Teams receive clear explanations of the nature of the vulnerabilities identified and can apply automated patches via [merge requests](https://docs.gitlab.com/ee/user/project/merge_requests/) generated directly by GitLab Duo. This feature helps secure development without slowing down development lifecycles.\n\nLearn more about GitLab Duo Vulnerability Explanation and Resolution by clicking on the image below to access our product tour.\n\n[![Vulnerability report interactive tour](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749673816/Blog/Content%20Images/Screenshot_2025-05-29_at_8.32.15%C3%A2__AM.png)](https://gitlab.navattic.com/ve-vr-short)\n\n### Key features of GitLab Duo\n\n* [GitLab Duo Chat](https://about.gitlab.com/blog/10-best-practices-for-using-ai-powered-gitlab-duo-chat/): This conversational feature processes and generates text and code intuitively. It allows users to quickly search for relevant information in large volumes of text, including in tickets, [epics](https://docs.gitlab.com/ee/user/group/epics/), source code, and [GitLab documentation](https://docs.gitlab.com/).\n\n* [GitLab Duo Self-Hosted](https://about.gitlab.com/blog/gitlab-duo-self-hosted-enterprise-ai-built-for-data-privacy/): GitLab Duo Self-Hosted allows companies with strict data privacy requirements to benefit from GitLab Duo's AI capabilities with flexibility in choosing deployment and LLMs from a list of supported options.\n\n* [GitLab Duo Code Suggestions](https://about.gitlab.com/direction/create/code_creation/code_suggestions/): Development teams benefit from automated code suggestions, allowing them to write secure code faster. Repetitive and routine coding tasks are automated, significantly speeding up software development lifecycles.\n\nGitLab Duo is not limited to these features. It offers a wide range of features designed to simplify and optimize software development. Whether it's automating testing, improving collaboration between teams, or strengthening project security, GitLab Duo is a complete solution for smart and efficient DevSecOps processes.\n\nLearn more about GitLab Duo Enterprise by clicking on the image below to access our product tour. \n\n[![GitLab Duo Enterprise interactive tour](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749673816/Blog/Content%20Images/Screenshot_2025-05-29_at_8.33.40%C3%A2__AM.png)](https://gitlab.navattic.com/duo-enterprise)",[717,9],{"slug":3822,"featured":6,"template":698},"what-is-a-large-language-model-llm","content:en-us:blog:what-is-a-large-language-model-llm.yml","What Is A Large Language Model Llm","en-us/blog/what-is-a-large-language-model-llm.yml","en-us/blog/what-is-a-large-language-model-llm",{"_path":3828,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3829,"content":3835,"config":3841,"_id":3843,"_type":14,"title":3844,"_source":16,"_file":3845,"_stem":3846,"_extension":19},"/en-us/blog/what-is-git-the-ultimate-guide-to-gits-role-and-functionality",{"title":3830,"description":3831,"ogTitle":3830,"ogDescription":3831,"noIndex":6,"ogImage":3832,"ogUrl":3833,"ogSiteName":686,"ogType":687,"canonicalUrls":3833,"schema":3834},"What is Git? The ultimate guide to Git's role and functionality","Want to complete your projects with Git? Discover all of Git's benefits and features in our comprehensive guide.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749673991/Blog/Hero%20Images/Git.jpg","https://about.gitlab.com/blog/what-is-git-the-ultimate-guide-to-gits-role-and-functionality","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"What is Git? The ultimate guide to Git's role and functionality\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"GitLab\"}],\n        \"datePublished\": \"2024-11-14\",\n      }",{"title":3830,"description":3831,"authors":3836,"heroImage":3832,"date":3837,"body":3838,"category":3839,"tags":3840},[1751],"2024-11-14","Git is a must-have tool in the world of modern software development. In this comprehensive guide, we explain in detail what the Git tool is, its role in source code versioning, and how it works. Whether you're a beginner or an expert, this guide will give you a deep understanding of Git and its many features.\n\n## What is Git?\n\nGit is a source control tool that has quickly become a must-have in the software development ecosystem. Git's ability to meticulously track project changes makes it an essential tool for developers aiming to efficiently manage their projects. Therefore, mastering Git has become a vital skill for anyone aiming to excel in the field of software development.\n\n### What is version control?\n\n[Version control](https://about.gitlab.com/topics/version-control/what-is-git-version-control/) enables you to track changes to a software's source code. Thus, a software's delivered version consists of a set of specific versions of each of its components and source code files. For example, an icon might have only been changed twice, while a code file might have undergone several dozen changes over time.\n\n## What are Git's features?\n\nIn development, maintaining rigorous management of changes to a software's source code is important. Without this, ensuring the consistency and reliability of development teams' work is impossible. Fine-tuned change management can also make it easier to identify the source of a problem. Similarly, it reduces the risk of conflicts and file overwriting. Indeed, Git facilitates and streamlines software versioning precisely for this purpose.\n\nTo better understand Git and how it works, below we've outlined some of the key features that make it easy to optimize source code management as well as collaboration across teams.\n\n### Visualization of your project history\n\nIn the software development ecosystem, [the commit history](https://about.gitlab.com/blog/keeping-git-commit-history-clean/) is a core pillar for tracking project progress on Git. That's why Git offers developers a detailed history of all changes made to the   \nsource code.\n\nFor each new commit, the following are recorded:\n\n* specific changes made to project files\n* an explanatory message from the developer who made the change\n\nThese elements help improve the development team's communication and mission, allowing them to more quickly understand the ins and outs of each change made to the code.\n\nIn addition to monitoring project developments, this history allows you to go back if necessary, cancel part of the changes or, conversely, fetch only part of the changes from one branch to another. This function therefore plays an essential role in maintaining the transparency, consistency, and quality of a project's source code in Git, as well as collaboration within the development team and operational efficiency to solve problems.\n\nCheck out our tutorial on [how to create your first Git commit](https://docs.gitlab.com/ee/tutorials/make_first_git_commit/).\n\n### Greater autonomy for teams\n\nAnother essential feature of the Git tool is [distributed development](https://git-scm.com/about/distributed). Thanks to its decentralized structure, Git allows development teams to work simultaneously on the same project. Each team member has their own copy of the project, where each of their changes can be versioned. This allows them to work autonomously on specific features while reducing conflict or overwriting risks. This approach offers great flexibility for developers who can then explore different ideas or experiment with new features without interfering with their colleagues' work.\n\nDistributed development also enhances resilience to server failures. Thus, even in the event of a failure, each person has a copy on which they can continue to work offline. Changes can then be synchronized once the server is available again, thereby reducing the risk of work disruption for development teams and update constraints for operational teams.\n\n### Optimizing development workflows\n\nOne of Git's most powerful features is the ability to [manage branches and their mergers (branching and merging)](https://git-scm.com/about/branching-and-merging). These allow teams to work in parallel in a collaborative and organized way. Each new code addition or bug fix can be independently developed and tested to ensure reliability. Developers can then simply merge changes into the project's main branch.\n\nBy adopting this approach, teams can track code evolution, collaborate easily and efficiently, reduce conflicts between different versions, and ensure continuous integration of developed features.\n\nUsing these two features, teams can develop projects continuously and in an agile manner while regularly deploying new code versions. This practice greatly facilitates change management while reducing the risk of errors.\n\n## What are Git's benefits?\n\nTo thoroughly understand Git, it's important to fully recognize the benefits it offers to your development teams:\n\n* **Decentralized version management:** With Git, each developer has a complete copy of the project history, allowing them to work independently.  \n* **A tool designed around security:** Unlike other source control tools, Git was designed from the outset to ensure the integrity of all elements of the repository with a cryptographic Secure Hash Algorithm (SHA1 and [SHA-256](https://about.gitlab.com/blog/gitlab-now-supports-sha256-repositories/) to date). This algorithm aims to protect the project's code and history from any modifications, whether malicious or not. In addition, each commit (creation of a new version) can be automatically signed (GPG) to ensure change traceability. This makes Git a particularly safe and secure tool, which guarantees the integrity and authenticity of your source code and its history.  \n* **A fast and effective tool:** The Git tool has been designed to maximize efficiency during development. Its speed allows developers to perform complex operations, such as commits, branching, and merging, in minimal time, even on large code bases. It also ensures a minimum fingerprint on the hard disk and during network exchanges. This efficiency then translates into rapid response times during backups, consultations, and project history changes.  \n* **Greater work flexibility:** Git supports a wide variety of development workflows. Whether you prefer centralized development models or more linear approaches, Git adapts easily. This ability to manage different workflows provides teams with numerous options for how they work.  \n* **Ease of integration:** Git excels in its ability to integrate with a wide array of existing development tools and platforms. The breadth of this compatibility allows teams to manage their projects more effectively by leveraging the best DevSecOps tools and practices.  \n* **A widely followed open-source project:** Another significant benefit of Git is that it's an open-source project supported by a dynamic and dedicated community which ensures its constant improvement. This active participation from individuals and companies in the Git community ensures the regular addition of new features and improvements through continuous updates.\n\n## What are Git's main commands?\n\nThe open-source Git project offers a wide variety of commands to make teamwork easier.  \nHere are some of the most commonly used commands.\n\n* **git init:** Initialize a new Git repository.  \n* **git clone \\[url\\]:** Clone an existing repository.  \n* **git add \\[file\\]:** Add a file to the index.  \n* **git commit:** Validate changes made.  \n* **git commit \\-m \"message\":** Validate changes with a message.  \n* **git status:** View the status of files in the working directory.  \n* **git push:** Send changes to remote repository.  \n* **git pull:** Fetch changes from the remote repository and merge them with the local repository.\n\nWhile these commands are essential to getting started with Git, it's important to note that there are plenty of other commands. See the [list of Git commands](https://git-scm.com/docs).\n\n## Git and GitLab\n\nGitLab is a collaborative open-source development platform covering all stages of the DevSecOps lifecycle and providing a Git server for efficient team collaboration.\n\nBeyond source code management, GitLab offers a complete suite enabling continuous integration and distribution, deliverables management, security and incident management, as well as all associated traceability, real-time task planning and tracking, deployment monitoring, software versioning, and the associated document space.\n\n## Git FAQs\n\n### Why use Git?\n\nGit is all about efficiency. Git's decentralized system based on branching and merging features allows development teams to work on the same project without interfering with others' work or, more importantly, creating version conflicts.\n\n### Is Git software?\n\nGit is an open-source project. Therefore, it's free and open to everyone. However, you need to [install Git](https://docs.gitlab.com/ee/topics/git/how_to_install_git/) on your device before you can start working.\n\n### What is a branch in Git?\n\nIn Git, a branch is a pointer to a change history. Thus, each main branch points to the last commit performed on it. It is therefore possible to have many parallel branches, each with its own history but the same root.\n\n### What is a commit?\n\nIn Git, a commit is a record of changes to a software's source code. Each commit is accompanied by an explanatory message that traces the history of all changes. This makes project tracking easier, and there's always the option to revert to earlier, functional versions if there's a problem.\n\n### What is the benefit of branches in Git?\n\nDeveloping features in branches allows developers to work simultaneously on several distinct features. In addition, this avoids compromising the main branch with unstable code. Moreover, implementing branches in Git is significantly more lightweight than in other version control systems.","open-source",[1041,9,803],{"slug":3842,"featured":6,"template":698},"what-is-git-the-ultimate-guide-to-gits-role-and-functionality","content:en-us:blog:what-is-git-the-ultimate-guide-to-gits-role-and-functionality.yml","What Is Git The Ultimate Guide To Gits Role And Functionality","en-us/blog/what-is-git-the-ultimate-guide-to-gits-role-and-functionality.yml","en-us/blog/what-is-git-the-ultimate-guide-to-gits-role-and-functionality",{"_path":3848,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3849,"content":3855,"config":3861,"_id":3863,"_type":14,"title":3864,"_source":16,"_file":3865,"_stem":3866,"_extension":19},"/en-us/blog/what-the-digital-operational-resilience-act-means-for-banks",{"title":3850,"description":3851,"ogTitle":3850,"ogDescription":3851,"noIndex":6,"ogImage":3852,"ogUrl":3853,"ogSiteName":686,"ogType":687,"canonicalUrls":3853,"schema":3854},"What the Digital Operational Resilience Act means for banks","Find out why financial institutions need to understand the DORA legislative framework introduced in the European Union to strengthen operational resilience.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098149/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%284%29_3LZkiDjHLjhqEkvOvBsVKp_1750098149751.png","https://about.gitlab.com/blog/what-the-digital-operational-resilience-act-means-for-banks","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"What the Digital Operational Resilience Act means for banks\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Joshua Carroll\"},{\"@type\":\"Person\",\"name\":\"Allie Holland\"}],\n        \"datePublished\": \"2025-01-15\",\n      }",{"title":3850,"description":3851,"authors":3856,"heroImage":3852,"date":3858,"body":3859,"category":694,"tags":3860},[3857,2179],"Joshua Carroll","2025-01-15","Developers play a critical role in ensuring banks remain competitive and compliant. One framework gaining significant attention is DORA. If you’re thinking of the [DevOps Research and Assessment (DORA) metrics](https://docs.gitlab.com/ee/user/analytics/dora_metrics.html), this is something different. The [Digital Operational Resilience Act](https://www.eiopa.europa.eu/digital-operational-resilience-act-dora_en) is a new regulatory framework focused on safeguarding financial institutions against digital disruptions. For developers, understanding DORA regulations is not just a regulatory necessity; it’s an opportunity to drive innovation and enhance the overall stability of their organizations. \n\n## What is DORA regulation?\n\nThe Digital Operational Resilience Act (DORA) is a legislative framework introduced by the European Union to strengthen the operational resilience of financial institutions. DORA aims to ensure that banks and other financial services providers can withstand, respond to, and recover from all types of information and communication technology (ICT) related disruptions and threats. DORA outlines specific requirements for risk management, incident reporting, testing, and the overall governance of digital operations.\n\n## Core requirements of DORA\n\nDORA introduces several critical requirements for financial institutions to ensure they can maintain operational continuity, including:\n\n1. **Risk management:** Organizations must establish systems to identify, assess, and manage risks related to their digital operations. DORA fundamentally redefines the landscape of ICT risk management by placing accountability at the executive level. Detailed in [Article 5](https://www.digital-operational-resilience-act.com/Article_5.html), the management body of an organization is now entrusted with the ultimate responsibility for overseeing ICT risk management. This includes conducting regular risk assessments and implementing strategies to mitigate identified vulnerabilities.   \n\n2. **Regular testing:** Financial institutions are required to conduct systematic testing of their ICT systems to ensure they can handle potential disruptions effectively. This includes stress testing, scenario analysis, and recovery simulations to evaluate the resilience of their operations.  \n\n3. **Incident reporting:** Significant ICT-related incidents must be reported to regulators within specified timeframes. This requirement enhances oversight and allows regulators to coordinate responses across the financial sector, ensuring a unified approach to managing crises. The most recent [Regulatory Technical Standards](https://www.eba.europa.eu/sites/default/files/2023-12/ecc72f1c-c68a-4e64-97dd-47470117c3ae/JC%202023%2070%20-%20%20CP%20on%20draft%20RTS%20and%20ITS%20on%20major%20incident%20reporting%20under%20DORA.pdf) proposes time limits for reporting of the initial notification of four hours after classification and 24 hours after detection of the incident, 72 hours for reporting of the intermediate report, and one month for the reporting of the final report.   \n\n4. **Third-party risk management:** DORA also focuses on managing risks associated with outsourcing services to third-party providers. Organizations must ensure that their partners adhere to the same stringent standards, conducting due diligence and regular assessments of third-party performance. One of the biggest shifts for a bank is oftentimes centered around the establishment of exit strategies, detailed in [Article 28](https://www.digital-operational-resilience-act.com/Article_28.html).\n\nOrganizations need to prepare for scenarios where a third-party provider can no longer meet their operational needs or compliance obligations. This proactive approach ensures continuity and minimizes disruption in critical services. GitLab offers a distinct advantage in this area, as our platform is cloud-agnostic. This flexibility allows organizations to easily adapt their operations and transition between service providers as needed, simplifying the implementation of effective exit strategies.\n\nFor those who are interested in learning a bit more about the specifics listed above, the formal regulation documentation can be found [here](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32022R2554).  \n\n## Why DORA matters to developers\n\nDORA is important for developers to understand for the following reasons:\n\n1. **Enhanced security posture:** For developers, DORA emphasizes the importance of robust cybersecurity measures. As cyber threats continue to evolve, being part of an organization that prioritizes security means you’ll need to build applications with security in mind from the beginning, with a shift [security left mindset](https://www.youtube.com/watch?v=XnYstHObqlA). Compliance with DORA requires implementing best practices in secure coding, conducting regular vulnerability assessments, and ensuring that security controls are integrated into the software development lifecycle.  \n2. **Focus on resilience:** DORA requires banks to have clear strategies for operational resilience. Developers must now design systems that go beyond surface level functionality, building applications that can withstand failures and protect against disruptions. Having a clear understanding of DORA can guide you in architecting applications that can seamlessly handle disruptions, whether from a technical failure or an external threat.  \n3. **Collaboration and cross-functional teams:** Implementing DORA effectively requires a collaborative approach, which could pose a challenge in siloed banking structures. Developers will need to work closely with cybersecurity teams, risk management, and compliance officers.   \n4. **Agility in incident response:** DORA mandates that organizations report and respond to incidents efficiently. Developers must be equipped to quickly address vulnerabilities and deploy fixes.   \n5. **Continuous improvement culture:** DORA encourages a culture of continuous improvement and testing. This requires the adoption of practices like chaos engineering and regular stress testing of applications to ensure they can handle unexpected scenarios. Embracing these methodologies will not only help meet regulatory requirements but also improve the overall quality and reliability of the software that is built.\n\n## GitLab's role in DORA compliance\n\nGitLab is prepared to help financial institutions meet DORA’s stringent requirements. With [security built into the earliest stages of deployment pipelines](https://about.gitlab.com/topics/ci-cd/shift-left-devops/), GitLab is strategically positioned to equip organizations with software that is [Secure by Design](https://about.gitlab.com/blog/secure-by-design-principles-meet-devsecops-innovation-in-gitlab-17/). \n\n* **Robust risk management:** GitLab’s built-in tools enable organizations to identify, assess, and manage risk across their digital landscape. By utilizing features like [issue tracking](https://docs.gitlab.com/ee/user/project/issues/index.html) and [merge requests](https://docs.gitlab.com/ee/user/project/merge_requests/), teams can collaboratively manage and document risks throughout the software development lifecycle. GitLab provides several tools that enable organizations to manage these requirements effectively:  \n      - **Audit logs and compliance dashboards:** GitLab's [audit logs](https://docs.gitlab.com/ee/user/compliance/audit_events.html) capture all activities within the platform, giving financial institutions a full history of changes made to code, configurations, and infrastructure. These logs allow compliance teams to review user actions and detect irregularities that could pose risks. Additionally, GitLab’s [compliance dashboard](https://docs.gitlab.com/ee/user/compliance/compliance_center/compliance_standards_adherence_dashboard.html) provides real-time visibility into which projects comply with established policies, making it easier to manage large-scale governance.  \n      - **Custom compliance frameworks:** GitLab allows organizations to create [custom compliance frameworks](https://docs.gitlab.com/ee/user/group/compliance_frameworks.html#:~:text=You%20can%20create%20a%20compliance,on%20which%20it%20is%20applied.) that are tailored to an organization's regulatory requirements and geographical regions. These frameworks ensure consistent enforcement of security and operational standards, meeting DORA’s systematic risk management objectives.  \n\n* **Comprehensive application security testing:** Security vulnerabilities pose significant regulatory, financial, and reputational risks. GitLab addresses these challenges by building security testing directly into its CI/CD pipelines, ensuring vulnerabilities are detected and mitigated before deployment. This approach leverages multiple [testing methodologies](https://about.gitlab.com/stages-devops-lifecycle/secure/):\n    - [Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/): Analyzes source code for security vulnerabilities.\n    - [Dynamic Application Security Testing (DAST)](https://docs.gitlab.com/ee/user/application_security/dast/): Tests running applications for security weaknesses.\n    - [Secret Detection](https://docs.gitlab.com/ee/user/application_security/secret_detection/): Prevents sensitive information from being exposed in code.\n    - [Fuzz Testing](https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing/): Identifies potential security issues by testing with random inputs.\n\n  GitLab’s security tools run automated tests that scan for vulnerabilities in code, containers, and third-party dependencies. These features help organizations meet the DORA requirement to continuously test IT systems, providing peace of mind that potential vulnerabilities are addressed before they become operational risks.\n\n  ![GitLab features for DORA requirements in EU](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098160/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098160209.png)\n\n* **Efficient incident reporting:** GitLab’s [project management capabilities](https://docs.gitlab.com/ee/topics/plan_and_track.html) enable teams to effectively log and track significant ICT-related incidents. This centralized documentation, combined with [continuous vulnerability scanning](https://docs.gitlab.com/ee/user/application_security/continuous_vulnerability_scanning/), facilitates timely reporting to regulators, enhances visibility, and supports compliance with DORA's incident reporting requirements.\n  [GitLab's incident management features](https://docs.gitlab.com/ee/operations/incident_management/incidents.html#:~:text=The%20incident%20summary%20can%20be,displays%20them%20below%20the%20summary.) streamline the workflow of remediation, making it easier for teams to identify, trace, and act on incidents as they arise.\n    - Incident management tools: GitLab includes built-in tools for managing incidents, serving as a centralized record for teams to report, assess, and mitigate issues effectively. Users can create incident records, assign ownership, and document the investigation and resolution process. This centralization not only streamlines incident management but also enables teams to trace back and determine accountability for each incident. By facilitating clear ownership and structured workflows, GitLab positions organizations to effectively meet DORA’s requirements for effective incident response plans.\n    - Real-time alerts and monitoring integrations: By integrating with monitoring tools such as [Prometheus](https://prometheus.io/) and Grafana, GitLab allows financial institutions to receive real-time alerts when issues arise. These alerts can trigger automated incident responses, helping teams address potential threats before they escalate, in line with DORA’s emphasis on quick reaction times.\n\n* **Third-party risk management:** GitLab enables organizations to work closely with third-party providers, ensuring they adhere to the same rigorous standards required by the industry. The platform provides both technical controls and governance features to manage third-party risks:\n    * Technical Controls\n       - [Dependency Scanning](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/): Automatically detects vulnerabilities in third-party libraries and open-source components\n      - [Software Composition Analysis](https://about.gitlab.com/blog/reduce-supply-chain-risk-with-smarter-vulnerability-prioritization/): Provides detailed inventory and security status of all external dependencies\n      -  [Container Scanning](https://docs.gitlab.com/ee/user/application_security/container_scanning/): Identifies vulnerabilities in third-party container images   \n\n   * Governance Features\n      - [Policy Enforcement](https://docs.gitlab.com/ee/user/application_security/policies/): Automatically enforce security policies for external code and components\n      -  [Integration Controls](https://docs.gitlab.com/ee/api/integrations.html): GitLab's API-first approach ensures secure and monitored integration with external systems\n      -   [Audit Trails](https://docs.gitlab.com/ee/user/compliance/audit_events.html): Maintain comprehensive logs of all third-party component usage and changes\n\n  These capabilities help organizations meet DORA's requirements for third-party risk management while maintaining operational efficiency.\n\nThe EU’s DORA regulations present new challenges for financial institutions, requiring them to enhance their governance, cybersecurity, and resilience frameworks. GitLab offers powerful features that address the key pillars of DORA, from incident management to cybersecurity testing and third-party risk management. By integrating GitLab into operational processes, financial institutions can streamline their compliance efforts, reduce risks, and ensure that they meet regulatory requirements with greater efficiency. GitLab provides a solid foundation for organizations seeking to stay ahead of the evolving regulatory landscape while maintaining strong security and operational resilience.\n\n> #### [Reach out](https://about.gitlab.com/solutions/finance/) to learn more about how GitLab can help meet your regulatory challenges.\n\n## Read more\n\n- [GitLab supports banks in navigating regulatory challenges](https://about.gitlab.com/blog/gitlab-supports-banks-in-navigating-regulatory-challenges/)\n- [Meet regulatory standards with GitLab security and compliance](https://about.gitlab.com/blog/meet-regulatory-standards-with-gitlab/)\n- [How to ensure separation of duties and enforce compliance with GitLab](https://about.gitlab.com/blog/ensuring-compliance/)\n",[571,694,496,9],{"slug":3862,"featured":6,"template":698},"what-the-digital-operational-resilience-act-means-for-banks","content:en-us:blog:what-the-digital-operational-resilience-act-means-for-banks.yml","What The Digital Operational Resilience Act Means For Banks","en-us/blog/what-the-digital-operational-resilience-act-means-for-banks.yml","en-us/blog/what-the-digital-operational-resilience-act-means-for-banks",{"_path":3868,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3869,"content":3875,"config":3880,"_id":3882,"_type":14,"title":3883,"_source":16,"_file":3884,"_stem":3885,"_extension":19},"/en-us/blog/why-are-organizations-moving-to-a-unified-devsecops-platform",{"title":3870,"description":3871,"ogTitle":3870,"ogDescription":3871,"noIndex":6,"ogImage":3872,"ogUrl":3873,"ogSiteName":686,"ogType":687,"canonicalUrls":3873,"schema":3874},"Why are organizations moving to a unified DevSecOps platform?","Learn about GitLab's comprehensive, unified DevSecOps platform, which integrates tools, enhances security, and leverages AI for efficient software development.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097063/Blog/Hero%20Images/Blog/Hero%20Images/securitylifecycle-light_securitylifecycle-light.png_1750097063583.png","https://about.gitlab.com/blog/why-are-organizations-moving-to-a-unified-devsecops-platform","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Why are organizations moving to a unified DevSecOps platform?\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Itzik Gan Baruch\"}],\n        \"datePublished\": \"2025-06-02\",\n      }",{"title":3870,"description":3871,"authors":3876,"heroImage":3872,"date":3877,"body":3878,"category":10,"tags":3879},[1612],"2025-06-02","In today’s modern software development landscape, many organizations are migrating to the cloud and adopting DevSecOps processes. However, this transition presents a significant challenge: a proliferation of tools and legacy systems not designed for modern development. To adapt these systems to DevSecOps, organizations must create integrations between multiple tools for task management, CI/CD, security, monitoring, and more. The result? Operational complexity, high maintenance costs, and disrupted collaboration between development and operations teams. Additionally, developers experience frustration as they constantly switch between different tools to complete a single development flow – from planning to production.\n\n![The complexity and operational costs of integrating multiple tools into a DevSecOps process](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097077/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750097077287.jpg)\n\n\u003Ccenter>\u003Ci>How complex it can be to integrate multiple tools into a DevSecOps process\u003C/i>\u003C/center>\n\n\u003Cbr>\u003C/br>\n\nThe good news is that a solution exists: A comprehensive DevSecOps platform offering a unified approach to software development.\n\nThese platforms are built for organizations operating in cloud-based and DevSecOps environments, consolidating all software development stages — from code management, CI/CD processes, task management, and security to AI-driven automation — into a single platform. Centralizing all software development workflows in a unified interface enables development and operations teams to work more efficiently, streamline communication, and minimize operational complexities and disruptions.\n\nFurthermore, the developer experience significantly improves — engineers are much happier working with a product designed specifically for modern development needs.\n\nIn the sections below, we’ll explore how GitLab helps teams overcome common challenges — whether it’s managing projects and tasks, ensuring security and compliance, or adopting AI-powered development tools – all within a single, unified platform.\n\n## Integrated Agile project management\n\nGitLab provides a holistic solution in which project and task management are fully integrated across all stages of the software development lifecycle, such as CI/CD, enabling real-time tracking of development progress. Issues and epics directly link to automation processes, allowing a seamless flow from planning to production deployment. This approach enhances transparency across teams, reduces delays, and ensures that all stakeholders have a clear view of the development status in real-time.\n\n![Issues and epics directly link to automation processes, allowing a seamless flow from planning to production deployment.](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097077/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750097077288.jpg)\n\n## Built-in security\nGitLab strongly emphasizes integrating security capabilities end-to-end (security first). The platform integrates a wide range of automated security scanners, including:\n\n- [Dependency Scanning](https://docs.gitlab.com/user/application_security/dependency_scanning/)\n- [Static Application Security Testing (SAST)](https://docs.gitlab.com/user/application_security/sast/)\n- [Dynamic Application Security Testing (DAST)](https://docs.gitlab.com/user/application_security/dast/)\n- [Secret Detection](https://docs.gitlab.com/user/application_security/secret_detection/)\n- [Container Scanning](https://docs.gitlab.com/user/application_security/container_scanning/)\n\n![Security scanning capabilities integrated into the CI/CD process at various development stages](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750097077/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750097077289.jpg)\n\n\u003Ccenter>\u003Ci>Security scanning capabilities integrated into the CI/CD process at various development stages\u003C/i>\u003C/center>\n\n\u003Cbr>\u003C/br>\n\nThese security checks are built directly into every phase of the software development lifecycle, including the CI/CD pipeline, to provide developers with immediate feedback on potential security issues early in the development cycle.\n\n## Compliance and regulatory requirements\n\nBeyond efficiency and user experience, many organizations — especially those in regulated industries such as financial institutions or large enterprises — must ensure their processes comply with strict security and compliance standards. They need the ability to enforce policies for different projects, such as mandating a security scanner every time a CI/CD pipeline runs on specific code branches (e.g., main or protected branches) or requiring specific approvals before merging code into the main branch.\n\nWith GitLab, this becomes easier through [Compliance Frameworks](https://about.gitlab.com/blog/introducing-custom-compliance-frameworks-in-gitlab/), a feature that allows organizations to define and enforce structured policies for selected projects. This ensures compliance with automatic regulatory and security requirements while maintaining a seamless and efficient developer workflow.\n\n## AI-powered development\n\n[GitLab Duo](https://about.gitlab.com/gitlab-duo/) provides AI-driven assistance across all development stages, eliminating the need to switch to external tools. Every AI-powered request is processed within the full context of the project and codebase, enabling smarter and more efficient work.\n\nAI can perform example tasks such as:\n- automatic task description generation\n- smart summarization of issue discussions, saving developers valuable time\n- advanced code review capabilities\n- code improvement and optimization suggestions\n- automated test generation\n- security vulnerability detection and remediation\n- troubleshooting root cause analysis for CI pipeline failures\n- privacy and Data Security\n\nUnderstanding the needs of regulated organizations, particularly in the public and financial sectors, GitLab offers a unique solution for running AI models in a secure environment. GitLab Duo Self-Hosted enables organizations to maintain full control over data privacy, security, and the deployment of large language models ([LLMs](https://about.gitlab.com/blog/what-is-a-large-language-model-llm/)) in their own infrastructure, ensuring:\n- data privacy protection\n- compliance with regulatory requirements\n- maximum security\n- AI benefits without external network dependencies or risks\n\n## Summary\n\nOrganizations need a comprehensive DevSecOps platform to streamline processes, enhance security, and accelerate innovation. GitLab delivers precisely that — a single application consolidating all essential development, security, and operational tools with built-in security integration and AI-powered automation.\n\nReady to see GitLab in action? Explore interactive demos of:\n\n- [GitLab Premium and Ultimate with Duo](https://gitlab.navattic.com/gitlab-premium-with-duo) – experience AI-powered development assistance\n\n- [Adding security to the CI/CD pipeline](https://gitlab.navattic.com/gitlab-scans) – see how integrated security scanning protects your software\n\n- [Compliance frameworks](https://gitlab.navattic.com/compliance) – discover how GitLab enforces policies across projects for better governance\n\n> Join the GitLab 18 virtual launch event to learn about the future of the DevSecOps platform, including the role of agentic AI. [Register today!](https://about.gitlab.com/eighteen/)",[9,496,848],{"slug":3881,"featured":6,"template":698},"why-are-organizations-moving-to-a-unified-devsecops-platform","content:en-us:blog:why-are-organizations-moving-to-a-unified-devsecops-platform.yml","Why Are Organizations Moving To A Unified Devsecops Platform","en-us/blog/why-are-organizations-moving-to-a-unified-devsecops-platform.yml","en-us/blog/why-are-organizations-moving-to-a-unified-devsecops-platform",{"_path":3887,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3888,"content":3892,"config":3899,"_id":3901,"_type":14,"title":3902,"_source":16,"_file":3903,"_stem":3904,"_extension":19},"/en-us/blog/why-enterprise-independence-matters-more-than-ever-in-devsecops",{"config":3889,"title":3890,"description":3891},{"noIndex":6},"Why enterprise independence matters more than ever in DevSecOps","As leaders question who controls their development infrastructure, GitLab's independence and transparency advantages have never been more relevant.\n",{"title":3890,"description":3891,"authors":3893,"date":3895,"body":3896,"category":781,"tags":3897,"heroImage":3898},[3894],"Robin Schulman","2025-09-02","For over a decade, GitLab has been committed to transparency, independence, and putting developers first. Today, as the industry evolves, this matters more than ever. Enterprise leaders are asking critical questions: Who ultimately controls your development infrastructure? How is your code being used in AI systems? What happens when vendor priorities shift away from your critical requirements?\n\nLast month, [we announced GitLab 18.3](https://about.gitlab.com/blog/gitlab-18-3-expanding-ai-orchestration-in-software-engineering/), the latest release of our AI-native DevSecOps platform. Agent Insights, part of GitLab Duo Agent Platform, provides visibility into agent decision-making processes. Expanded AI model support means no vendor lock-in. Enhanced governance controls help enable compliance across multiple jurisdictions.\n\nThese aren't just features. They're demonstrations of the transparency, independence, and developer-first approach that defines GitLab. Here's how this strategy translates into practice.\n\n\u003Cdiv style=\"padding:56.25% 0 0 0;position:relative;\">\u003Ciframe src=\"https://player.vimeo.com/video/1115249475?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" title=\"Who is GitLab_Robin_090225_FINAL\">\u003C/iframe>\u003C/div>\u003Cscript src=\"https://player.vimeo.com/api/player.js\">\u003C/script>\n\n## AI transparency across the DevSecOps lifecycle\n\n**At GitLab, our decade-long commitment to transparency directly addresses these concerns.** As artificial intelligence becomes increasingly integrated into development workflows, organizations are rightfully concerned about how their code and data are being used for AI training.\n\nThe GitLab [AI Transparency Center](https://about.gitlab.com/ai-transparency-center/), launched in April 2024, provides clear documentation of our data governance practices, privacy protections, and ethical AI principles. Unlike platforms that may operate AI features with unclear data usage policies, GitLab prioritizes transparency so that customers  can understand [exactly how their data is processed](https://docs.gitlab.com/user/gitlab_duo/data_usage/), stored, and protected — with no training on that data.\n\nOur approach extends to model flexibility and vendor independence. While some platforms lock customers into single, large language model (LLM) providers, creating additional vendor dependencies and potential single points of failure, GitLab's AI features are powered by a variety of models. This approach enables us to support a wide range of use cases, providing customers with the flexibility to align with their strategic priorities.\n\nAs we further develop GitLab Duo Agent Platform, we remain focused on data control and maintaining comprehensive human-in-the-loop controls. And GitLab Duo Self-Hosted provides complete data sovereignty with air-gapped deployment options, zero-day data retention policies, and the ability to process all AI requests within your own infrastructure.\n\nSince May 2024, we've also maintained an [AI continuity plan](https://handbook.gitlab.com/handbook/product/ai/continuity-plan/) with an industry-leading commitment: the ability to evaluate and move to a new model within 30 days if a provider changes its practices regarding customer data. This proactive approach to AI vendor risk management reflects our dedication to customer control.\n\n## Choice in deployment, choice in cloud provider\n\n**You should be able to choose how and where to deploy your DevSecOps environment.** GitLab provides genuine deployment flexibility. Organizations can choose from on-premises installations, multi-tenant SaaS, or GitLab Dedicated, our fully managed single-tenant SaaS solution, without sacrificing functionality or facing artificial restrictions designed to drive ecosystem lock-in. GitLab is also cloud-neutral, allowing customers to use the cloud provider that best suits their business needs and environment.\n\nThis flexibility proves invaluable when navigating complex jurisdictional requirements and regulatory challenges. When new data localization laws emerge — as we've seen across the European Union and other regions — organizations using GitLab can rapidly adapt their deployment strategies without being constrained by ecosystem dependencies.\n\nFrom a procurement and risk management perspective, platform independence also provides crucial leverage in contract negotiations. Organizations aren't forced into restrictive licensing agreements that prioritize vendor interests over customer needs. This independence becomes particularly critical as enterprises become more vigilant about who controls their AI stack.\n\n## Security and compliance: Built-in and always a priority\n\n**Security and compliance are now equally important to development features and should be built into the platform, not retrofitted as an afterthought.** GitLab's single platform approach provides significant advantages over fragmented platforms that rely on third-party add-ins to match basic security and governance features. This architectural difference has significant implications for possible legal risk, operational efficiency, and regulatory compliance. Each additional tool in the chain represents another potential point of failure, another set of terms and conditions to negotiate, and another source of risk.\n\nGitLab provides comprehensive built-in security and compliance capabilities, including custom compliance frameworks, dynamic application security testing (DAST), API fuzz testing, coverage-guided fuzzing, and infrastructure-as-code testing. These capabilities are natively integrated into the platform, offering consistent policy enforcement and reducing the compliance complexity and additional costs that come with managing multiple third-party tools.\n\nOur [compliance center](https://docs.gitlab.com/user/compliance/compliance_center/) provides a central location for teams to manage their compliance standards, adherence reporting, violations reporting, and compliance frameworks for their group. This unified approach to compliance management is particularly valuable for organizations operating in highly-regulated industries where audit trails and compliance documentation are critical.\n\n## Staying close to our open source community\n\n**The best tools are shaped by the people who use them.** Our commitment to open source and engagement with our community has been core to GitLab since our founding. For instance, our [Co-Create program](https://about.gitlab.com/community/co-create/) is a collaborative initiative that enables customers to work directly with GitLab engineers to contribute features, fixes, and enhancements to the GitLab platform.\n\nOur transparency value remains fundamental to our business. An example of this is our [open issue tracker](https://gitlab.com/groups/gitlab-org/-/issues), where customers can follow our progress and engage directly with the GitLab team in discussions about ways we can improve our product. We recently launched our [Healthy Backlog Initiative](https://about.gitlab.com/blog/inside-gitlabs-healthy-backlog-initiative/) to give customers even greater visibility into our planning and direct their feedback to places with the greatest impact.\n\nOur approach enables organizations to contribute to and benefit from open source innovation while maintaining the governance, audit trails, and security controls required for regulated environments.\n\n## Data governance: Your data, your control\n\n**You maintain complete control over your data and how it's processed.** Data governance has become an increasingly critical factor in enterprise technology decisions, driven by a complex web of national and regional data protection laws and growing concern about control over sensitive intellectual property — like source code, customer insights, strategic initiatives, and competitive intelligence.\n\nWith GitLab, you can manage who has access to AI-powered capabilities within the platform, extending beyond simple access controls to encompass encryption standards and audit capabilities aligned to regulatory frameworks. Also, customers' code and data are never used to train AI models.\n\n## The choice is clear\nGitLab continues to lead in AI-native DevSecOps platform innovation – our recent [18.3 release](https://about.gitlab.com/blog/gitlab-18-3-expanding-ai-orchestration-in-software-engineering/) demonstrates this – while staying true to the independence and transparency commitments that have always guided us.\n\nCustomers have a choice and it's clear: retaining control vs. vendor lock-in; transparency vs. uncertainty; dedication to innovation vs. whims of the larger ecosystem.\n\nGitLab provides the foundation for sustainable digital transformation that balances innovation with independence, helping you achieve business value for your customers.\n\n[Try GitLab Ultimate with GitLab Duo for free today.](https://about.gitlab.com/free-trial/)",[717,9,848,719,803],"https://res.cloudinary.com/about-gitlab-com/image/upload/v1756500636/wmey6kqzzuhirk88w2de.png",{"featured":91,"template":698,"slug":3900},"why-enterprise-independence-matters-more-than-ever-in-devsecops","content:en-us:blog:why-enterprise-independence-matters-more-than-ever-in-devsecops.yml","Why Enterprise Independence Matters More Than Ever In Devsecops","en-us/blog/why-enterprise-independence-matters-more-than-ever-in-devsecops.yml","en-us/blog/why-enterprise-independence-matters-more-than-ever-in-devsecops",{"_path":3906,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3907,"content":3913,"config":3920,"_id":3922,"_type":14,"title":3923,"_source":16,"_file":3924,"_stem":3925,"_extension":19},"/en-us/blog/why-gitlab-is-deprecating-compliance-pipelines-in-favor-of-security-policies",{"title":3908,"description":3909,"ogTitle":3908,"ogDescription":3909,"noIndex":6,"ogImage":3910,"ogUrl":3911,"ogSiteName":686,"ogType":687,"canonicalUrls":3911,"schema":3912},"GitLab moves from compliance pipelines to security policies","Learn about our decision to deprecate compliance pipelines and how to migrate to pipeline execution policies. The process is detailed in this tutorial.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098128/Blog/Hero%20Images/Blog/Hero%20Images/security-checklist_security-checklist.png_1750098128272.png","https://about.gitlab.com/blog/why-gitlab-is-deprecating-compliance-pipelines-in-favor-of-security-policies","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Why GitLab is deprecating compliance pipelines in favor of security policies\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Ian Khor\"}],\n        \"datePublished\": \"2024-10-01\",\n      }",{"title":3914,"description":3909,"authors":3915,"heroImage":3910,"date":3917,"body":3918,"category":694,"tags":3919},"Why GitLab is deprecating compliance pipelines in favor of security policies",[3916],"Ian Khor","2024-10-01","GitLab compliance pipelines ensure security- and compliance-related jobs in applicable projects are run in accordance with compliance frameworks. Similarly, scan execution policies assure GitLab security scans are run in pipelines in a compliant manner.\n\nWhat we’ve learned from users is that they’d like to capture benefits offered by each feature through a single, simpler solution. Users would like to combine the flexibility of [compliance pipelines](https://docs.gitlab.com/ee/user/project/settings/index.html#compliance-pipeline-configuration) with the simplicity and versatility of [security policies](https://docs.gitlab.com/ee/user/application_security/policies/).\n\nTo meet this request, we developed a new feature, [pipeline execution policies](https://docs.gitlab.com/ee/user/application_security/policies/pipeline_execution_policies.html), to help users enforce customized CI/CD jobs for all applicable projects. Pipeline execution policies perform a similar function to compliance pipelines, but with increased focus on compliance enforcement, flexibility, and a foundation to build and solve for more use cases in the future.\n\nTo reduce confusion, compliance pipelines have been [deprecated](https://docs.gitlab.com/ee/update/deprecations.html#compliance-pipelines) in 17.3 now that pipeline execution policies are available and, as part of the deprecation, we are providing a step-by-step workflow for migrating from compliance pipelines to pipeline execution policy type in 17.5.\n\nYou can follow along with the work we’re doing with the deprecation through this [epic](https://gitlab.com/groups/gitlab-org/-/epics/11275).\n\n![compliance pipelines - image 1](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098139/Blog/Content%20Images/Blog/Content%20Images/image3_aHR0cHM6_1750098139599.png)\n\n## Why are we deprecating compliance pipelines?\n\nTo understand the reason behind this change, we first need to understand the difference between the [compliance management](https://about.gitlab.com/direction/govern/compliance/compliance-management/) and [policy management](https://about.gitlab.com/direction/govern/security_policies/security_policy_management/) features in GitLab. With compliance management, we are focused on helping you understand your compliance posture, providing tools to report to auditors, and surfacing compliance risks in a way that helps you take action.\n\nWe are also focused on increasing compliance visibility of framework requirements, violations, and audit events throughout the entire DevSecOps lifecycle. Our compliance management offering also establishes a direct association between controls and automations configured through policies back into compliance requirements established through compliance frameworks.\n\nPolicy management works hand in hand with compliance programs, as well as supporting scalable security initiatives. Policies give organizations a central location to globally enforce security controls, compliance controls, and automate security and compliance workflows. Security policies will continue to address core use cases across the lifecycle, such as defining enforcement around CI/CD component usage, blocking risks related to dependency and package management, and automating vulnerability management workflows to address security and compliance controls.\n\nTherefore, to ensure we provide the greatest value for our security and compliance users, we are deprecating compliance pipelines and providing a migration path for users to security policies. Not only does this make it clear and simple to the user how and when to enforce jobs as part of a project pipeline, but it also makes the distinction between compliance management and policy management in GitLab clearer. Compliance management is focused on compliance visibility, and policy management is focused on compliance and security enforcement across your entire GitLab instance.\n\n## What is the timeline for the deprecation and removal of compliance pipelines?\n\nThe iteration plan below can be found in the [issue that details the work we are doing](https://gitlab.com/groups/gitlab-org/-/epics/11275) to deprecate and remove compliance pipelines:\n\n**[Deprecation announcement](https://docs.gitlab.com/ee/update/deprecations.html#compliance-pipelines)**\n* Compliance pipeline deprecation and removal was announced in 17.3\n\n**[Compliance pipelines maintenance mode](https://gitlab.com/groups/gitlab-org/-/epics/12324)**\n* Adding banners and migration workflow, and docs\n* Released in 17.5\n\n**[Deter new compliance pipelines](https://gitlab.com/groups/gitlab-org/-/epics/14150)**\n* Adding warning banners for new pipelines\n* Encourage users to try the pipeline execution policy instead\n* Scheduled to start work on this 17.6\n* Scheduled to be released 17.8\n\n**[Compliance pipelines removal](https://gitlab.com/groups/gitlab-org/-/epics/12325) (Remove compliance pipelines)**\n* Provide tools to trial the removal and validate any errors\n* Scheduled to start work on this 17.8\n* Scheduled to be released 19.0\n\nAs you can see, we will start with the deprecation of compliance pipelines and the introduction of pipeline execution policy in the 17.3 release. \n\nLeading up to the removal of compliance pipelines in the 19.0 release, we are including new ways to inform and warn users about the upcoming removal. We are providing warning banners on new pipelines, as well as a workflow that can be used to migrate compliance pipelines to pipeline execution policy.\n\nWe ‘ll remove compliance pipelines in the 19.0 release, but provide a reverse feature flag in the milestones leading up that will help users test the removal and understand any impact prior to the removal date.\n\n## How to migrate your compliance pipelines to pipeline execution policy?\n\nThere are two ways users can access the workflow for migrating compliance pipelines to pipeline execution policy.\n\n1. When creating a new compliance framework, there will now be a warning banner that allows users to start using pipeline execution policy type instead of compliance frameworks:\n\n![compliance pipelines - image 3](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098140/Blog/Content%20Images/Blog/Content%20Images/image4_aHR0cHM6_1750098139599.png)\n\n2. When editing an existing compliance framework, there will now be a warning banner that enables users to migrate their compliance pipelines to pipeline execution policy type – if they have a compliance pipeline configured.\n\n![compliance pipelines - image 2](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098140/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098139601.png)\n\nSelecting either \"Create policy\" or \"Migrate pipeline to a policy\" in either workflow will bring users to the \"New policy\" creation page in the \"Security Policies\" section. This will allow users to create a new security policy instead of a compliance pipeline. Or, if you migrate an existing compliance pipeline, the new policy will be populated with the compliance pipeline YAML as the remote source for the policy. Also, the policy scope will be populated with the framework from which you are migrating. \n\nThe policy will target all projects with that label for enforcement and apply enforcement of jobs defined in your remote file, now the pipeline execution YAML. By default, the new policy will be configured with the “override” mode, which will override downstream projects' `.gitlab-ci.yml` with the configuration you have defined (similar to compliance pipelines).\n\n![compliance pipelines - image 4](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098140/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098139604.png)\n\nAlternatively, you may use the “Inject” mode, which introduces a new set of reserved stages to run security and compliance jobs in isolation in a tamper-proof manner, without disrupting the project pipeline, and without coordinating with project teams to define stage names in their pipeline config. \n\nWith this approach, be sure to remove the `include:project`, which is no longer needed for this mode. And, depending on your version, ensure job names are unique (required in GitLab 17.2 and 17.3). In GitLab 17.4, we introduced additional enhancements for [managing conflicts](https://docs.gitlab.com/ee/user/application_security/policies/pipeline_execution_policies.html#job-naming-best-practice) for additional flexibility.\n\n## Start your migration today\n\nWe want to ensure that all GitLab users who are using compliance pipelines are fully aware of the deprecation of compliance pipelines in 17.3 and its eventual removal by the 19.0 release as a breaking change. \n\nWe are asking users to start migrating their compliance pipelines to the pipeline execution policy type as soon as possible, before the removal of compliance pipelines in GitLab 19.0.\n\nIf there are any questions, please contact your customer service representative or GitLab support for any help.\n\n> Follow along with the compliance pipeline deprecation progress in [this epic](https://gitlab.com/groups/gitlab-org/-/epics/11275).\n\n> Share feedback in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/491924) regarding any gaps are blockers for adopting pipeline execution policies.",[694,827,9,109],{"slug":3921,"featured":91,"template":698},"why-gitlab-is-deprecating-compliance-pipelines-in-favor-of-security-policies","content:en-us:blog:why-gitlab-is-deprecating-compliance-pipelines-in-favor-of-security-policies.yml","Why Gitlab Is Deprecating Compliance Pipelines In Favor Of Security Policies","en-us/blog/why-gitlab-is-deprecating-compliance-pipelines-in-favor-of-security-policies.yml","en-us/blog/why-gitlab-is-deprecating-compliance-pipelines-in-favor-of-security-policies",{"_path":3927,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3928,"content":3933,"config":3938,"_id":3940,"_type":14,"title":3941,"_source":16,"_file":3942,"_stem":3943,"_extension":19},"/en-us/blog/why-hackerone-gets-love-letters-from-developers",{"title":3929,"description":3930,"ogTitle":3929,"ogDescription":3930,"noIndex":6,"ogImage":2744,"ogUrl":3931,"ogSiteName":686,"ogType":687,"canonicalUrls":3931,"schema":3932},"Why HackerOne gets love letters from its developers","Learn how HackerOne is making developers more productive while ensuring that security is built into their software development processes.","https://about.gitlab.com/blog/why-hackerone-gets-love-letters-from-developers","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Why HackerOne gets love letters from its developers\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sharon Gaudin\"}],\n        \"datePublished\": \"2023-11-14\",\n      }",{"title":3929,"description":3930,"authors":3934,"heroImage":2744,"date":3935,"body":3936,"category":972,"tags":3937},[756],"2023-11-14","At [HackerOne](/customers/hackerone/), a cybersecurity company, using the GitLab DevSecOps Platform has changed developers’ team experience and culture so much they’re basically sending the company love letters about their jobs.\n\nThis is no exaggeration, according to HackerOne Senior Director of Platform and Infrastructure Russell Owen, who spoke to an audience at GitLab’s DevSecOps World Tour in Mountain View, California, this fall. The 11-year-old company adopted GitLab in 2018 for source code and issues management, CI/CD, and security and compliance – features that didn’t exist in its previous tooling system. Since then, developers have become more productive — and happier.\n\nHackerOne isn’t alone here. According to GitLab’s [2023 Global DevSecOps Survey](https://about.gitlab.com/developer-survey/), 28% of the more than 5,000 respondents said using DevOps made their developers happier. Productivity, efficiency, and automation go a long way to making developers’ jobs easier and more enjoyable.\n\n## Measuring for DevSecOps impact\n\n“We run surveys every quarter. Are the developers happy? What do they find frustrating? Where's the friction?” Owen said in an on-stage interview with [Sherrod Patching](https://about.gitlab.com/company/team/#spatching), vice president of customer success management at GitLab. “We compare our metrics across the industry to see how we're doing.”\n\nAnd they’re doing well. “For instance, just making our [CI/CD pipelines](/blog/how-to-learn-ci-cd-fast/) as tight as possible makes people more effective. We've done a lot of work on optimizing that inside of GitLab,” Owen added. “And we get what count as love letters from our developers. People are so excited because the pipeline times have come down substantially, and it has a direct impact on the productivity of the team.”\n\nWhile Owen said he definitely wants his DevSecOps team members to be happy, he also wants productivity to be high. And he noted the importance of evaluating a variety of metrics — from happiness to the number of merge requests and releases — to enable teams to quantify their impact on the company. And those numbers are good, too.\n\nWith GitLab, merge requests per engineer are up by 50% over the last year, and they’ve cut their code release time by 50% over the last two years, according to Owen, who added that the number of quarterly releases to production jumped by 73% since two years ago.\n\n“A lot of that is from just shaving time off the CI/CD pipeline,” he said. “That’s efficiency. That’s productivity. It’s important because I need to be able to justify our work and expenses. These kinds of metrics make it very easy for me to say: ‘Investing in this area has a measurable return on investment.’”\n\n## Using GitLab for security and compliance\n\nWhen a business is known around the world for cybersecurity, assuring the safety and reliability of its own code has to be a priority. HackerOne uses GitLab to ensure that security is built into their software products and processes, according to Owen.\n\nHe explained their need, for example, to keep the number of people who have access to their production systems to a minimum. The fewer people who can touch the system, the fewer potential entry points to introduce vulnerabilities. The platform enables the team to build in guidelines mandating that any change needs to be reviewed and approved by the infrastructure team. So when teams make a change to the infrastructure, it’s only applied to the system once it’s been accepted.\n\n“Changes are being reviewed by people who have expertise in the area,” said Owen. “This really allows efficiency, but also maintains security. And it's all done inside GitLab.”\n\nHackerOne also relies on the GitLab platform to make sure they are staying in line with strict [industry compliance requirements](/blog/meet-regulatory-standards-with-gitlab/). Limiting the number of people who have access to the system is an example of that.\n\nOwen said they also use GitLab to [stay compliant](/blog/top-5-compliance-features-to-leverage-in-gitlab/) with FedRAMP, the Federal Risk and Authorization Management Program, a set of standards the U.S. federal government requires for moving sensitive information into the cloud.\n\n“We do more and more work with containers and FedRAMP requires that they be scanned before being moved into production,” he added. “You can’t just bring them into your infrastructure directly. We stage and scan everything in GitLab — all the containers, particularly third-party containers. Then, if they meet our criteria, we move them on so they’re eligible for production.”\n\nWith GitLab, HackerOne remains FedRAMP compliant for all of its federal customers.\n\n## Looking to an AI future\n\nWhen asked what he thought they’d be focused on over the next five years, Owen replied, “AI, AI, AI.”\n\nFor HackerOne, which brings in immense amounts of data, Owen said he’s looking to artificial intelligence to help them cull that flood of information to find patterns and pull out what will be useful to their customers.\n\n“Whatever business you're in, for a long time, there has been a lot of data,” Owen said. “And you can't help but wonder how you can use it to provide value to your customers, right? There has been a sea change in the last few years, from AI being something that was kind of theoretically interesting to something that is operationally useful. So if you're not doing AI... Well, I'm sure we’re all doing AI. You have to do it now. And the tools are just incredible.”\n\n_HackerOne’s Owen is a software developer, designer, and IT leader with more than 20 years of experience building advanced systems. He previously worked at Google as an engineering manager in the company’s privacy and security department, as well as at Research in Motion, where he was responsible for the Blackberry’s infrastructure design._\n\n_Read more GitLab customer stories on our [customers page](https://about.gitlab.com/customers/)._",[9,496,717,974],{"slug":3939,"featured":91,"template":698},"why-hackerone-gets-love-letters-from-developers","content:en-us:blog:why-hackerone-gets-love-letters-from-developers.yml","Why Hackerone Gets Love Letters From Developers","en-us/blog/why-hackerone-gets-love-letters-from-developers.yml","en-us/blog/why-hackerone-gets-love-letters-from-developers",{"_path":3945,"_dir":3946,"_draft":6,"_partial":6,"_locale":7,"content":3947,"config":3952,"_id":3954,"_type":14,"title":3955,"_source":16,"_file":3956,"_stem":3957,"_extension":19},"/en-us/blog/external-url/overcome-ai-sprawl-with-a-value-stream-management-approach","external-url",{"title":3948,"description":3949,"heroImage":3950,"date":3721,"category":10,"tags":3951},"Overcome AI sprawl with a Value Stream Management approach","From The Source: Learn how an AI strategy based on Value Stream Management can stop AI sprawl and supply chain constraints and drive ROI.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665000/Blog/Hero%20Images/display-the-source-article-overcome-ai-sprawl-image-0492-1800x945-fy25.png",[9,1016,1039],{"featured":6,"externalUrl":3953},"https://about.gitlab.com/the-source/ai/overcome-ai-sprawl-with-a-value-stream-management-approach/","content:en-us:blog:external-url:overcome-ai-sprawl-with-a-value-stream-management-approach.yml","Overcome Ai Sprawl With A Value Stream Management Approach","en-us/blog/external-url/overcome-ai-sprawl-with-a-value-stream-management-approach.yml","en-us/blog/external-url/overcome-ai-sprawl-with-a-value-stream-management-approach",{"_path":3959,"_dir":246,"_draft":6,"_partial":6,"_locale":7,"seo":3960,"content":3966,"config":3970,"_id":3972,"_type":14,"title":3973,"_source":16,"_file":3974,"_stem":3975,"_extension":19},"/en-us/blog/3-gitlab-features-to-level-up-devsecops-workflows",{"title":3961,"description":3962,"ogTitle":3961,"ogDescription":3962,"noIndex":6,"ogImage":3963,"ogUrl":3964,"ogSiteName":686,"ogType":687,"canonicalUrls":3964,"schema":3965},"3 GitLab features to level up DevSecOps workflows","Fix broken pipelines faster, better understand security vulnerabilities, and filter out false positives with our latest platform improvements.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665762/Blog/Hero%20Images/blog-gl17-release-hero-17-0-93-1800x945-fy25__1_.png","https://about.gitlab.com/blog/3-gitlab-features-to-level-up-devsecops-workflows","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"3 GitLab features to level up DevSecOps workflows\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Salman Ladha\"}],\n        \"datePublished\": \"2024-10-29\",\n      }",{"title":3961,"description":3962,"authors":3967,"heroImage":3963,"date":2637,"body":3968,"category":848,"tags":3969},[1710],"Last month, we, along with the GitLab community, introduced more than 140 improvements to our AI-powered DevSecOps platform to help you build better and more secure software, faster. With that much product innovation, we know it can be difficult to keep track of the latest GitLab has to offer. So, each quarter, we’re spotlighting the most impactful capabilities to help you consolidate toolchains, boost development efficiency, and improve application security. Here are three new features [released in GitLab](https://about.gitlab.com/releases/categories/releases/) over the past few months that make an immediate impact on your software development.\n\n > Learn why GitLab was named a Leader in the [2024 Gartner® Magic Quadrant™ for DevOps Platforms](https://about.gitlab.com/blog/gitlab-named-a-leader-in-the-2024-gartner-magic-quadrant-for-devops/) and the [2024 Gartner® Magic Quadrant™ for AI Code Assistants](https://about.gitlab.com/blog/gitlab-named-a-leader-in-2024-gartner-magic-quadrant-for-ai-code-assistants/).\n\n## Root Cause Analysis: Diagnose broken pipelines faster\n\n[Developers spend less than a quarter of their time on code creation](https://about.gitlab.com/developer-survey/), according to our 2024 Global DevSecOps Survey. The bulk of their time is consumed by administrative tasks, planning, and troubleshooting — many of which can be accelerated with AI.\n\nFor example, diagnosing broken pipelines is a frustrating task for developers, which requires them to tediously scour through dense log files to identify the cause of the error. This often leads to trial-and-error fixes, sleuthing for solutions on Google, or asking a peer for support. This is a practical scenario where [GitLab Duo Root Cause Analysis](https://about.gitlab.com/blog/developing-gitlab-duo-blending-ai-and-root-cause-analysis-to-fix-ci-cd/) can meaningfully help developers.\n\nRoot Cause Analysis analyzes log files to uncover the core issue behind an error message in a CI/CD pipeline. Not only does it provide teams with insight into what caused the issue, but it also suggests a fix to help resolve the issue faster.\n\nWith less time spent on troubleshooting, developers can focus on building differentiated products to help their organizations win.\n\nGitLab Duo Root Cause Analysis is available as a [GitLab Duo Enterprise add-on](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/?type=free-trial&toggle=gitlab-duo-pro).\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/sTpSLwX5DIs?si=JZSgd7GTTk4y6mre\" frameborder=\"0\" allowfullscreen=\"true\">\u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Vulnerability Explanation: Quickly understand security risks\n\nWe know that developers are playing [an even greater role in the remediation of security vulnerabilities](https://about.gitlab.com/developer-survey/). However, not every developer is well-versed in cybersecurity or has a working knowledge of the tactics, techniques, and procedures a threat actor will use to exploit an application. This creates a knowledge gap, which is exposed when vulnerabilities are uncovered.\n\n[GitLab Duo Vulnerability Explanation](https://about.gitlab.com/the-source/ai/understand-and-resolve-vulnerabilities-with-ai-powered-gitlab-duo/) bridges the knowledge gap between security and development teams. It gives developers a detailed description of the vulnerability infecting their code, real-world examples of how attackers can exploit the vulnerable code, and practical suggestions for remediation.\n\nWith this feature, you can level up your security skills, resolve vulnerabilities faster, and help create a proactive security culture — all while lightening the load on your security teams.\nGitLab Duo Vulnerability Explanation is available as a [GitLab Duo Enterprise add-on](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/?type=free-trial&toggle=gitlab-duo-pro).\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/MMVFvGrmMzw?si=Zsx-91078XSNNUSm\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Advanced SAST: Filter out the noise\n\nFalse positives are a [top frustration](https://about.gitlab.com/developer-survey/2024/security-compliance/) for both security and development teams. Unfortunately, this is a common complaint of traditional Static Application Security Testing (SAST). While SAST is great at integrating security early in the software development lifecycle, its value diminishes when it produces inaccurate results. “Drowning in a backlog of vulnerabilities” is a reality for many security and development teams, often resulting in tension between them.\n\n[Advanced SAST](https://about.gitlab.com/blog/gitlab-advanced-sast-is-now-generally-available/), our newest security scanner, uses a proprietary detection engine with rules informed by in-house security research to identify exploitable vulnerabilities. It delivers more accurate results, so security and development teams don’t have to sort through the noise of false-positive results, shortening triage time, improving development velocity, and decreasing friction between teams.\n\nAdvanced SAST is available in the [GitLab Ultimate tier](https://about.gitlab.com/pricing/ultimate/).\n\n\u003C!-- blank line -->\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/xDa1MHOcyn8?si=Ff4HjNpvv5eXsSNH\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\u003C!-- blank line -->\n\n## Put these features to work today\n\nAt GitLab, we’re committed to making it easier for teams to build software, faster. Capabilities like GitLab Duo Root Cause Analysis, GitLab Duo Vulnerability Explanation, and GitLab Advanced SAST are just a few of the recent innovations we’ve delivered to help developers and security teams level up their DevSecOps workflows. To learn more, check out our [releases page](https://about.gitlab.com/releases/categories/releases/).\n\n> Get started with these new features today with [a free trial of GitLab Ultimate](https://gitlab.com/-/trials/new?glm_content=default-saas-trial&glm_source=about.gitlab.com%2F).",[848,719,9,694,109],{"slug":3971,"featured":91,"template":698},"3-gitlab-features-to-level-up-devsecops-workflows","content:en-us:blog:3-gitlab-features-to-level-up-devsecops-workflows.yml","3 Gitlab Features To Level Up Devsecops Workflows","en-us/blog/3-gitlab-features-to-level-up-devsecops-workflows.yml","en-us/blog/3-gitlab-features-to-level-up-devsecops-workflows",19,[679,703,726,746,768,789,810,834,855],1758326245055]