[{"data":1,"prerenderedAt":722},["ShallowReactive",2],{"/en-us/blog/lee-tickett-my-gitlab-journey/":3,"navigation-en-us":40,"banner-en-us":467,"footer-en-us":484,"Lee Tickett":694,"next-steps-en-us":707},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":30,"_id":33,"_type":34,"title":35,"_source":36,"_file":37,"_stem":38,"_extension":39},"/en-us/blog/lee-tickett-my-gitlab-journey","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"From user, to advocate, to contributor: my GitLab journey","Three years (as a user and as a contributor) with GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749681735/Blog/Hero%20Images/cover_photo.jpg","https://about.gitlab.com/blog/lee-tickett-my-gitlab-journey","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"From user, to advocate, to contributor: my GitLab journey\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Lee Tickett\"}],\n        \"datePublished\": \"2020-11-13\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Lee Tickett","2020-11-13","{::options parse_block_html=\"true\" /}\n\n\n\n\nI have had a passion for technology since before I can remember. Thirteen\nyears ago I took the plunge, quit my day job, and started an IT development\nand support company called [Tickett Enterprises\nLimited](https://www.tickett.net). For the last three years, GitLab has been\na part of my journey.\n\n\n## 3 Years Ago \n\nWe were (and still are) using a helpdesk system we built ourselves. It does\nexactly what we need it to do - and any time it doesn’t, we change it. The\nmost important feature of the system is reporting. Specifically,\nfacilitating our monthly billing process; with a click of a button, we\ngenerate timesheets and invoices for all of our clients.\n\n\nThough I was aware of Git (and GitHub), I had not heard of GitLab. We were\nusing SVN in its most basic form (single repository for all projects and no\nbranching), with an integration so all commits would create notes in our\nhelpdesk.\n\n\n## 2.5 Years Ago\n\nWe decided that SVN was no longer fit for purpose. Our top issues were: \n\n* never knowing whether the code in our repository matched what was deployed\n\n* not being able to work collaboratively on projects\n\n* feature/knowledge limitations\n\n* Git was the industry standard \n\n\nWhile most of these issues were due to the way we were using SVN, we were\nkeen to adopt a more popular system. I don’t remember how I found GitLab,\nbut I did, and spun up a local on-prem instance of Community Edition (CE)\nusing separate projects/repositories and basic branching. If you are\nconsidering running a local instance, I recommend the [Bitnami\nappliance/.ova](https://bitnami.com/stack/gitlab).\n\n\nIt took some time to get used to local vs remote and to remember to push as\nwell as commit, but we picked it up pretty quickly.\n\n\n## 2 Years Ago\n\nWe wanted to use GitLab to help us improve our processes so we:\n\n* built a little UI for project creation (using the GitLab API). This\nensures new projects fit our naming standards, contain our standard template\nfiles, have our standard master/test/dev branches, contain the relevant\nmembers, and use our webhooks\n\n* recreated the helpdesk integration we had with SVN (every commit and\ncomment is replicated as a note on our helpdesk)\n\n* unaware of GitLab EE, we created a custom merge request approval process\nusing webhooks. Our master branch is always protected - a merge request\nrequires 2 approvals from 2 distinct reviewers (one for code and one for\nfunctionality)\n\n\n## 1.5 Years Ago\n\nA bit late to the party, but finally we set up the GitLab runner to automate\nour build, spin up our database, execute our unit tests and report test\ndetails and code coverage. GitLab CI for .NET was not as well documented as\nother use cases leading to a lot of trial and error when setting up the\nrunner.\n\n\nWe are using the Windows runner configured to use a standard shell (which I\nthink is no longer supported). We will either be moving to powershell on\nwindows or possibly using docker images. Here’s a sample .gitlab-ci.yml\n\n\n```yml\n\nstages:\n  - build\n  - test\n\nvariables:\n  CI_DEBUG_TRACE: \"false\"\n  ASSEMBLY_VERSION: \"1.0.4\"\n  \nbuild:\n stage: build\n script:\n  - 'C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\nuget restore'\n  - '\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\MSBuild\\15.0\\bin\\msbuild\" /t:Restore,Clean,ReBuild /t:Database:Publish /p:Configuration=Debug;Platform=\"Any CPU\" /p:SqlPublishProfilePath=Database.publish.xml'\n  - 'ping 192.168.99.99 -n 1 -w 10000 2>nul || type nul>nul'\n artifacts:\n  paths:\n   - Tests/bin/\n\ntest:\n stage: test\n script:\n  - 'c:\\GitLab-Runner\\opencover\\OpenCover.Console.exe -returntargetcode:1000 -filter:\"+[*]* -[nunit*]* -[*Tests*]*\" -register -target:\"C:\\Program Files (x86)\\NUnit.org\\nunit-console\\nunit3-console.exe\" -targetargs:\"Tests\\Tests.csproj --result=testresult.xml;transform=C:\\gitlab-runner\\nunit3-junit.xslt\"'\n coverage: '/^Visited Branches .*(\\(\\d+\\.?\\d*\\))/'\n dependencies:\n  - build\n artifacts:\n  reports:\n   junit: testresult.xml\n```\n\n\nWe were building another customization to allow us to search for code across\nall repositories. Unfortunately, we hit a limitation because the API did not\nallow searching anything but the default branch.\n\n\nAt this point, while Googling for help getting CI up and running, I learned\nthat GitLab is open-source. So I thought maybe I could extend the API to\nsupport searching any branch. This lead to [my first\ncontribution](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/28069).\n\n\n## 1 Year Ago\n\nAt this point, I was completely new to all of the technologies, techniques,\nand best practices used by GitLab but found myself participating in my first\n[GitLab hackathon](https://about.gitlab.com/community/hackathon/). Somehow,\nI managed to take joint first prize!\n\n\nMy first few contributions were achieved by modifying my production GitLab\ninstallation (not ideal). So it was time to get the [GitLab Development Kit\n(GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit) up and running.\nThis was certainly not without its challenges (many of which I suspect stem\nfrom me being in the minority of GitLab contributors running Windows).\n\n\nI have since contributed to the [GDK\nproject](https://gitlab.com/gitlab-org/gitlab-development-kit) and joined\nthe GDK office hour calls to help shape the way forward and resolve some of\nthe problems and frustrations.\n\n\nAt this point, I was leearning a lot. Not just about the tools and languages\nbut about the best practices and work ethos within the GitLab team. Better\nyet, I was able to start taking some of these learnings back to the office.\n\n\n## 0.5 Years Ago\n\nI attended GitLab Commit - London 2019. This really helped to confirm my\nsuspicions; we are only scraping the surface of GitLab's capabilities.\n\n\nOn a few occasions, I wondered whether GitLab may not be a good fit for my\ncompany as I watched huge companies like Porsche and Goldman Sachs present.\nA [presentation](https://www.youtube.com/watch?v=t0Eh1sq9r5s) by Huss\nEl-Sheikh from startup 9fin helped ease my concerns.\n\n\nAround this time, I moved from Windows to Ubuntu to make it easier to work\nwith GDK.\n\n\nI continued to learn a lot from my contributions, feedback, and interactions\nwith the GitLab team, again applying what I could back in the office. Much\naround the languages/technologies I hadn’t previously worked with (namely\nruby, postgres and vue), but also other takeaways such as:\n\n* when carrying out code reviews ask questions rather than give instructions\n(“what do you think about x?” is more productive than “change this to y”)\n\n* GitLab CI is capable of automating a lot of what we currently do by hand\n(e.g. code review for best practices)\n\n* always try to add tests when making code changes\n\n\nI am a firm believer of documenting processes, decisions, and rationale.\nThere’s nothing worse than someone saying “we do it this way” without being\nable to back that up with reasoning. With that in mind, we implemented Merge\nRequest Templates to ensure our team was consistent in our approach to\ncoding, testing, and releasing.\n\n\nBy now our development team had plenty of experience with GitLab and we were\nstarting to move our support team over. To help our team leads monitor merge\nrequests, we adopted 2 simple departmental labels (`Support`/`Development`)\nand used our webhook engine to ensure every MR is automatically labelled.\n\n\n## Today / What’s Next\n\nIn preparation for a transition to .NET core, deprecation of the Windows\nshell runner and a desire to start testing our frontend (web), I started\nputting a CI script together using docker and the\nmcr.microsoft.com/dotnet/core/sdk:latest image. The .gitlab-ci.yml looks\nlike;\n\n\n```yml\n\nstages:  \n  - build\n  - test\n\nvariables:\n  CI_DEBUG_TRACE: \"false\"\n  ASSEMBLY_VERSION: \"1.0.1\"\n\nbuild:\n stage: build\n tags:\n  - docker\n script:\n  - 'dotnet build'\n\ntest:\n stage: test\n tags:\n  - docker\n script:\n  - 'nohup dotnet run --project Web &'\n  - 'apt-get update'\n  - 'apt-get install -y unzip'\n  - 'wget https://chromedriver.storage.googleapis.com/83.0.4103.14/chromedriver_linux64.zip'\n  - 'unzip chromedriver_linux64.zip -d ~/'\n  - 'rm chromedriver_linux64.zip'\n  - 'mv -f ~/chromedriver /usr/local/bin/chromedriver'\n  - 'chown root:root /usr/local/bin/chromedriver'\n  - 'chmod 0755 /usr/local/bin/chromedriver'\n  - 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'\n  - 'sh -c ''echo \"deb https://dl.google.com/linux/chrome/deb/ stable main\" >> /etc/apt/sources.list.d/google.list'''\n  - 'apt-get update'\n  - 'apt-get install -y google-chrome-stable'\n  - 'dotnet test -l:trx Tests/Tests.csproj /p:CollectCoverage=true'\n coverage: '/Total\\s*\\|.*\\|\\s(\\d+\\.?\\d*)%\\s*\\|.*\\|/'\n```\n\n\nAnd the tests look something like;\n\n\n```c#\n    public class UiTests : IDisposable\n    {\n        private readonly Process _webServerProcess;\n        private readonly IWebDriver _driver;\n\n        [Fact]\n        public void ClickNavPrivacyPolicy()\n        {\n            _driver.Navigate()\n                .GoToUrl(\"http://localhost:5000/\");\n\n            var link = _driver.FindElement(By.LinkText(\"Privacy\"));\n            link.Click();\n\n            Assert.Equal(\"http://localhost:5000/Home/Privacy\", _driver.Url);\n        }\n\n        public UiTests()\n        {\n            ChromeOptions chromeOptions = new ChromeOptions();\n            chromeOptions.AddArguments(\"headless\", \"no-sandbox\");\n            _driver = new ChromeDriver(chromeOptions);\n\n            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) return;\n\n            _webServerProcess = new Process\n            {\n                StartInfo = {\n                    WorkingDirectory = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, \"..\", \"..\", \"..\", \"..\", \"Web\"),\n                    FileName = $\"dotnet.exe\",\n                    Arguments = \" run\",\n                    UseShellExecute = true,\n                }\n            };\n            _webServerProcess.Start();\n        }\n\n        private void KillWebServer()\n        {\n            if (_webServerProcess != null && !_webServerProcess.HasExited)\n            {\n                _webServerProcess.Kill();\n            }\n        }\n\n        public void Dispose()\n        {\n            _driver.Dispose();\n            KillWebServer();\n        }\n    }\n```\n\n\nYou can see some conditional code in there which allows Selenium tests to\nwork both locally on our development machines and remotely on our GitLab\nrunner. If you have a better way of achieving this, please leave a comment.\nI would love to chat and learn!\n\n\nI also want to start introducing some linting like we see in the GitLab\nproject to enforce rules around code formatting (spaces, carriage returns,\nindentation, etc.). I have started to look at JetBrains Resharper (R#)\ncommand-line but haven’t had enough time to implement it yet. Ideally. I\nwould like to start with just a rule or two and then slowly introduce more,\nbut it looks quite tricky to take this approach. Please let me know if\nyou’ve been able to achieve this!\n\n\nI would also like to lose our helpdesk and start using GitLab issues,\nservice desk, timelogs, etc. I am working on identifying the gaps and\nworking with the product managers to understand whether it is realistic to\nfill those gaps within the GitLab product. Alternatively, I will be looking\nto build some additional “bolt-ons” using webhooks and the API.\n\n\nWhile investigating gaps, I stumbled upon the [GitLab-Triage\nproject](https://gitlab.com/gitlab-org/gitlab-triage) and I expect we'll use\nthis to automate various workflows. I managed to help close a few issues and\neven create a few additional features which would make it work for us by\n[contributing to the GitLab-Triage\nproject](https://gitlab.com/gitlab-org/gitlab-triage/-/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&author_username=leetickett).\n\n\nWe also added more labels (`needs code review` & `needs functional review`)\nfor our merge request approval process now. We can see where we are and what\nneeds to be done at a glance. We previously relied on an MR checklist that\nwe are deprecating.\n\n\n![Merge request\nchecklist](https://about.gitlab.com/images/blogimages/lee-tickett-my-gitlab-journey/mr_checklist.png)\n\n\n![Merge requests with\nlabels](https://about.gitlab.com/images/blogimages/lee-tickett-my-gitlab-journey/merge_requests_with_labels.png)\n\n\n## Contributing to GitLab \n\n\nI am very proud to have joined the GitLab Core Team. Thanks to everyone who\nhas held my hand and patiently assisted me with contributions. \n\n\nWith the release of Microsoft Windows Subsystem for Linux v2, I have gone\nback to running Windows on my laptop with GDK running in Ubuntu on WSL2.\nThis is working brilliantly for me at the moment (the way Visual Studio Code\nhandles things especially is really cool).\n\n\nI now have 95 [merged merge\nrequests!](https://gitlab.com/dashboard/merge_requests?scope=all&utf8=%E2%9C%93&state=merged&author_username=leetickett)\nand have been helping several others get started contributing (getting GDK\nup and running etc). Once this crazy pandemic is over and we can start to\nsocialise again, I would like to try and start some sort of local\nmeetup/group.\n\n\nI would like to help make it easier to connect GitLab users. I have visions\nof a mechanism to search for others based:\n\n* the size of their user base \n\n* the languages they are using\n\n* the feature they are using\n\n\nAt present, we have several tools (Gitter, Issues, Forum etc) but there is a\nstrong reliance on being engaged and stumbling on questions/support\nrequests. I suspect many of us would be happy to have other users reach out\ndirectly.\n\n\nIf you need any more information around:\n\n* getting your development environment/tools setup on Windows 10\n\n* getting CI working with .NET and SQL Server projects\n\n* building customisations using GitLab webhooks and API\n\n\n...or would like to see a demo of anything discussed above, I would be happy\nto oblige!\n\n\nI would love to connect with others who are either looking to, or already\nusing GitLab for:\n\n* .NET projects\n\n* customer helpdesk \n\n* customer billing (using timelogs)\n\n\nThanks for reading! Here's a picture of me and the family repping with our\nGitLab merch!\n\n\n![The tickett family repping\nGitLab](https://about.gitlab.com/images/blogimages/lee-tickett-my-gitlab-journey/landing_page.png)\n","unfiltered",[23,24,25,26,27,28,29],"CI/CD","community","user stories","workflow","open source","DevOps","collaboration",{"slug":31,"featured":6,"template":32},"lee-tickett-my-gitlab-journey","BlogPost","content:en-us:blog:lee-tickett-my-gitlab-journey.yml","yaml","Lee Tickett My Gitlab Journey","content","en-us/blog/lee-tickett-my-gitlab-journey.yml","en-us/blog/lee-tickett-my-gitlab-journey","yml",{"_path":41,"_dir":42,"_draft":6,"_partial":6,"_locale":7,"data":43,"_id":463,"_type":34,"title":464,"_source":36,"_file":465,"_stem":466,"_extension":39},"/shared/en-us/main-navigation","en-us",{"logo":44,"freeTrial":49,"sales":54,"login":59,"items":64,"search":394,"minimal":425,"duo":444,"pricingDeployment":453},{"config":45},{"href":46,"dataGaName":47,"dataGaLocation":48},"/","gitlab logo","header",{"text":50,"config":51},"Get free trial",{"href":52,"dataGaName":53,"dataGaLocation":48},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":55,"config":56},"Talk to sales",{"href":57,"dataGaName":58,"dataGaLocation":48},"/sales/","sales",{"text":60,"config":61},"Sign in",{"href":62,"dataGaName":63,"dataGaLocation":48},"https://gitlab.com/users/sign_in/","sign in",[65,109,206,211,315,375],{"text":66,"config":67,"cards":69,"footer":92},"Platform",{"dataNavLevelOne":68},"platform",[70,76,84],{"title":66,"description":71,"link":72},"The most comprehensive AI-powered DevSecOps Platform",{"text":73,"config":74},"Explore our Platform",{"href":75,"dataGaName":68,"dataGaLocation":48},"/platform/",{"title":77,"description":78,"link":79},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":80,"config":81},"Meet GitLab Duo",{"href":82,"dataGaName":83,"dataGaLocation":48},"/gitlab-duo/","gitlab duo ai",{"title":85,"description":86,"link":87},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":88,"config":89},"Learn more",{"href":90,"dataGaName":91,"dataGaLocation":48},"/why-gitlab/","why gitlab",{"title":93,"items":94},"Get started with",[95,100,105],{"text":96,"config":97},"Platform Engineering",{"href":98,"dataGaName":99,"dataGaLocation":48},"/solutions/platform-engineering/","platform engineering",{"text":101,"config":102},"Developer Experience",{"href":103,"dataGaName":104,"dataGaLocation":48},"/developer-experience/","Developer experience",{"text":106,"config":107},"MLOps",{"href":108,"dataGaName":106,"dataGaLocation":48},"/topics/devops/the-role-of-ai-in-devops/",{"text":110,"left":111,"config":112,"link":114,"lists":118,"footer":188},"Product",true,{"dataNavLevelOne":113},"solutions",{"text":115,"config":116},"View all Solutions",{"href":117,"dataGaName":113,"dataGaLocation":48},"/solutions/",[119,143,167],{"title":120,"description":121,"link":122,"items":127},"Automation","CI/CD and automation to accelerate deployment",{"config":123},{"icon":124,"href":125,"dataGaName":126,"dataGaLocation":48},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[128,131,135,139],{"text":23,"config":129},{"href":130,"dataGaLocation":48,"dataGaName":23},"/solutions/continuous-integration/",{"text":132,"config":133},"AI-Assisted Development",{"href":82,"dataGaLocation":48,"dataGaName":134},"AI assisted development",{"text":136,"config":137},"Source Code Management",{"href":138,"dataGaLocation":48,"dataGaName":136},"/solutions/source-code-management/",{"text":140,"config":141},"Automated Software Delivery",{"href":125,"dataGaLocation":48,"dataGaName":142},"Automated software delivery",{"title":144,"description":145,"link":146,"items":151},"Security","Deliver code faster without compromising security",{"config":147},{"href":148,"dataGaName":149,"dataGaLocation":48,"icon":150},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[152,157,162],{"text":153,"config":154},"Application Security Testing",{"href":155,"dataGaName":156,"dataGaLocation":48},"/solutions/application-security-testing/","Application security testing",{"text":158,"config":159},"Software Supply Chain Security",{"href":160,"dataGaLocation":48,"dataGaName":161},"/solutions/supply-chain/","Software supply chain security",{"text":163,"config":164},"Software Compliance",{"href":165,"dataGaName":166,"dataGaLocation":48},"/solutions/software-compliance/","software compliance",{"title":168,"link":169,"items":174},"Measurement",{"config":170},{"icon":171,"href":172,"dataGaName":173,"dataGaLocation":48},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[175,179,183],{"text":176,"config":177},"Visibility & Measurement",{"href":172,"dataGaLocation":48,"dataGaName":178},"Visibility and Measurement",{"text":180,"config":181},"Value Stream Management",{"href":182,"dataGaLocation":48,"dataGaName":180},"/solutions/value-stream-management/",{"text":184,"config":185},"Analytics & Insights",{"href":186,"dataGaLocation":48,"dataGaName":187},"/solutions/analytics-and-insights/","Analytics and insights",{"title":189,"items":190},"GitLab for",[191,196,201],{"text":192,"config":193},"Enterprise",{"href":194,"dataGaLocation":48,"dataGaName":195},"/enterprise/","enterprise",{"text":197,"config":198},"Small Business",{"href":199,"dataGaLocation":48,"dataGaName":200},"/small-business/","small business",{"text":202,"config":203},"Public Sector",{"href":204,"dataGaLocation":48,"dataGaName":205},"/solutions/public-sector/","public sector",{"text":207,"config":208},"Pricing",{"href":209,"dataGaName":210,"dataGaLocation":48,"dataNavLevelOne":210},"/pricing/","pricing",{"text":212,"config":213,"link":215,"lists":219,"feature":302},"Resources",{"dataNavLevelOne":214},"resources",{"text":216,"config":217},"View all resources",{"href":218,"dataGaName":214,"dataGaLocation":48},"/resources/",[220,253,275],{"title":221,"items":222},"Getting started",[223,228,233,238,243,248],{"text":224,"config":225},"Install",{"href":226,"dataGaName":227,"dataGaLocation":48},"/install/","install",{"text":229,"config":230},"Quick start guides",{"href":231,"dataGaName":232,"dataGaLocation":48},"/get-started/","quick setup checklists",{"text":234,"config":235},"Learn",{"href":236,"dataGaLocation":48,"dataGaName":237},"https://university.gitlab.com/","learn",{"text":239,"config":240},"Product documentation",{"href":241,"dataGaName":242,"dataGaLocation":48},"https://docs.gitlab.com/","product documentation",{"text":244,"config":245},"Best practice videos",{"href":246,"dataGaName":247,"dataGaLocation":48},"/getting-started-videos/","best practice videos",{"text":249,"config":250},"Integrations",{"href":251,"dataGaName":252,"dataGaLocation":48},"/integrations/","integrations",{"title":254,"items":255},"Discover",[256,261,265,270],{"text":257,"config":258},"Customer success stories",{"href":259,"dataGaName":260,"dataGaLocation":48},"/customers/","customer success stories",{"text":262,"config":263},"Blog",{"href":264,"dataGaName":5,"dataGaLocation":48},"/blog/",{"text":266,"config":267},"Remote",{"href":268,"dataGaName":269,"dataGaLocation":48},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":271,"config":272},"TeamOps",{"href":273,"dataGaName":274,"dataGaLocation":48},"/teamops/","teamops",{"title":276,"items":277},"Connect",[278,283,287,292,297],{"text":279,"config":280},"GitLab Services",{"href":281,"dataGaName":282,"dataGaLocation":48},"/services/","services",{"text":284,"config":285},"Community",{"href":286,"dataGaName":24,"dataGaLocation":48},"/community/",{"text":288,"config":289},"Forum",{"href":290,"dataGaName":291,"dataGaLocation":48},"https://forum.gitlab.com/","forum",{"text":293,"config":294},"Events",{"href":295,"dataGaName":296,"dataGaLocation":48},"/events/","events",{"text":298,"config":299},"Partners",{"href":300,"dataGaName":301,"dataGaLocation":48},"/partners/","partners",{"backgroundColor":303,"textColor":304,"text":305,"image":306,"link":310},"#2f2a6b","#fff","Insights for the future of software development",{"altText":307,"config":308},"the source promo card",{"src":309},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":311,"config":312},"Read the latest",{"href":313,"dataGaName":314,"dataGaLocation":48},"/the-source/","the source",{"text":316,"config":317,"lists":319},"Company",{"dataNavLevelOne":318},"company",[320],{"items":321},[322,327,333,335,340,345,350,355,360,365,370],{"text":323,"config":324},"About",{"href":325,"dataGaName":326,"dataGaLocation":48},"/company/","about",{"text":328,"config":329,"footerGa":332},"Jobs",{"href":330,"dataGaName":331,"dataGaLocation":48},"/jobs/","jobs",{"dataGaName":331},{"text":293,"config":334},{"href":295,"dataGaName":296,"dataGaLocation":48},{"text":336,"config":337},"Leadership",{"href":338,"dataGaName":339,"dataGaLocation":48},"/company/team/e-group/","leadership",{"text":341,"config":342},"Team",{"href":343,"dataGaName":344,"dataGaLocation":48},"/company/team/","team",{"text":346,"config":347},"Handbook",{"href":348,"dataGaName":349,"dataGaLocation":48},"https://handbook.gitlab.com/","handbook",{"text":351,"config":352},"Investor relations",{"href":353,"dataGaName":354,"dataGaLocation":48},"https://ir.gitlab.com/","investor relations",{"text":356,"config":357},"Trust Center",{"href":358,"dataGaName":359,"dataGaLocation":48},"/security/","trust center",{"text":361,"config":362},"AI Transparency Center",{"href":363,"dataGaName":364,"dataGaLocation":48},"/ai-transparency-center/","ai transparency center",{"text":366,"config":367},"Newsletter",{"href":368,"dataGaName":369,"dataGaLocation":48},"/company/contact/","newsletter",{"text":371,"config":372},"Press",{"href":373,"dataGaName":374,"dataGaLocation":48},"/press/","press",{"text":376,"config":377,"lists":378},"Contact us",{"dataNavLevelOne":318},[379],{"items":380},[381,384,389],{"text":55,"config":382},{"href":57,"dataGaName":383,"dataGaLocation":48},"talk to sales",{"text":385,"config":386},"Get help",{"href":387,"dataGaName":388,"dataGaLocation":48},"/support/","get help",{"text":390,"config":391},"Customer portal",{"href":392,"dataGaName":393,"dataGaLocation":48},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":395,"login":396,"suggestions":403},"Close",{"text":397,"link":398},"To search repositories and projects, login to",{"text":399,"config":400},"gitlab.com",{"href":62,"dataGaName":401,"dataGaLocation":402},"search login","search",{"text":404,"default":405},"Suggestions",[406,408,412,414,418,422],{"text":77,"config":407},{"href":82,"dataGaName":77,"dataGaLocation":402},{"text":409,"config":410},"Code Suggestions (AI)",{"href":411,"dataGaName":409,"dataGaLocation":402},"/solutions/code-suggestions/",{"text":23,"config":413},{"href":130,"dataGaName":23,"dataGaLocation":402},{"text":415,"config":416},"GitLab on AWS",{"href":417,"dataGaName":415,"dataGaLocation":402},"/partners/technology-partners/aws/",{"text":419,"config":420},"GitLab on Google Cloud",{"href":421,"dataGaName":419,"dataGaLocation":402},"/partners/technology-partners/google-cloud-platform/",{"text":423,"config":424},"Why GitLab?",{"href":90,"dataGaName":423,"dataGaLocation":402},{"freeTrial":426,"mobileIcon":431,"desktopIcon":436,"secondaryButton":439},{"text":427,"config":428},"Start free trial",{"href":429,"dataGaName":53,"dataGaLocation":430},"https://gitlab.com/-/trials/new/","nav",{"altText":432,"config":433},"Gitlab Icon",{"src":434,"dataGaName":435,"dataGaLocation":430},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":432,"config":437},{"src":438,"dataGaName":435,"dataGaLocation":430},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":440,"config":441},"Get Started",{"href":442,"dataGaName":443,"dataGaLocation":430},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":445,"mobileIcon":449,"desktopIcon":451},{"text":446,"config":447},"Learn more about GitLab Duo",{"href":82,"dataGaName":448,"dataGaLocation":430},"gitlab duo",{"altText":432,"config":450},{"src":434,"dataGaName":435,"dataGaLocation":430},{"altText":432,"config":452},{"src":438,"dataGaName":435,"dataGaLocation":430},{"freeTrial":454,"mobileIcon":459,"desktopIcon":461},{"text":455,"config":456},"Back to pricing",{"href":209,"dataGaName":457,"dataGaLocation":430,"icon":458},"back to pricing","GoBack",{"altText":432,"config":460},{"src":434,"dataGaName":435,"dataGaLocation":430},{"altText":432,"config":462},{"src":438,"dataGaName":435,"dataGaLocation":430},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":468,"_dir":42,"_draft":6,"_partial":6,"_locale":7,"title":469,"button":470,"image":475,"config":479,"_id":481,"_type":34,"_source":36,"_file":482,"_stem":483,"_extension":39},"/shared/en-us/banner","is now in public beta!",{"text":471,"config":472},"Try the Beta",{"href":473,"dataGaName":474,"dataGaLocation":48},"/gitlab-duo/agent-platform/","duo banner",{"altText":476,"config":477},"GitLab Duo Agent Platform",{"src":478},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":480},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":485,"_dir":42,"_draft":6,"_partial":6,"_locale":7,"data":486,"_id":690,"_type":34,"title":691,"_source":36,"_file":692,"_stem":693,"_extension":39},"/shared/en-us/main-footer",{"text":487,"source":488,"edit":494,"contribute":499,"config":504,"items":509,"minimal":682},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":489,"config":490},"View page source",{"href":491,"dataGaName":492,"dataGaLocation":493},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":495,"config":496},"Edit this page",{"href":497,"dataGaName":498,"dataGaLocation":493},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":500,"config":501},"Please contribute",{"href":502,"dataGaName":503,"dataGaLocation":493},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":505,"facebook":506,"youtube":507,"linkedin":508},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[510,533,589,618,652],{"title":66,"links":511,"subMenu":516},[512],{"text":513,"config":514},"DevSecOps platform",{"href":75,"dataGaName":515,"dataGaLocation":493},"devsecops platform",[517],{"title":207,"links":518},[519,523,528],{"text":520,"config":521},"View plans",{"href":209,"dataGaName":522,"dataGaLocation":493},"view plans",{"text":524,"config":525},"Why Premium?",{"href":526,"dataGaName":527,"dataGaLocation":493},"/pricing/premium/","why premium",{"text":529,"config":530},"Why Ultimate?",{"href":531,"dataGaName":532,"dataGaLocation":493},"/pricing/ultimate/","why ultimate",{"title":534,"links":535},"Solutions",[536,541,543,545,550,555,559,562,566,571,573,576,579,584],{"text":537,"config":538},"Digital transformation",{"href":539,"dataGaName":540,"dataGaLocation":493},"/topics/digital-transformation/","digital transformation",{"text":153,"config":542},{"href":155,"dataGaName":153,"dataGaLocation":493},{"text":142,"config":544},{"href":125,"dataGaName":126,"dataGaLocation":493},{"text":546,"config":547},"Agile development",{"href":548,"dataGaName":549,"dataGaLocation":493},"/solutions/agile-delivery/","agile delivery",{"text":551,"config":552},"Cloud transformation",{"href":553,"dataGaName":554,"dataGaLocation":493},"/topics/cloud-native/","cloud transformation",{"text":556,"config":557},"SCM",{"href":138,"dataGaName":558,"dataGaLocation":493},"source code management",{"text":23,"config":560},{"href":130,"dataGaName":561,"dataGaLocation":493},"continuous integration & delivery",{"text":563,"config":564},"Value stream management",{"href":182,"dataGaName":565,"dataGaLocation":493},"value stream management",{"text":567,"config":568},"GitOps",{"href":569,"dataGaName":570,"dataGaLocation":493},"/solutions/gitops/","gitops",{"text":192,"config":572},{"href":194,"dataGaName":195,"dataGaLocation":493},{"text":574,"config":575},"Small business",{"href":199,"dataGaName":200,"dataGaLocation":493},{"text":577,"config":578},"Public sector",{"href":204,"dataGaName":205,"dataGaLocation":493},{"text":580,"config":581},"Education",{"href":582,"dataGaName":583,"dataGaLocation":493},"/solutions/education/","education",{"text":585,"config":586},"Financial services",{"href":587,"dataGaName":588,"dataGaLocation":493},"/solutions/finance/","financial services",{"title":212,"links":590},[591,593,595,597,600,602,604,606,608,610,612,614,616],{"text":224,"config":592},{"href":226,"dataGaName":227,"dataGaLocation":493},{"text":229,"config":594},{"href":231,"dataGaName":232,"dataGaLocation":493},{"text":234,"config":596},{"href":236,"dataGaName":237,"dataGaLocation":493},{"text":239,"config":598},{"href":241,"dataGaName":599,"dataGaLocation":493},"docs",{"text":262,"config":601},{"href":264,"dataGaName":5,"dataGaLocation":493},{"text":257,"config":603},{"href":259,"dataGaName":260,"dataGaLocation":493},{"text":266,"config":605},{"href":268,"dataGaName":269,"dataGaLocation":493},{"text":279,"config":607},{"href":281,"dataGaName":282,"dataGaLocation":493},{"text":271,"config":609},{"href":273,"dataGaName":274,"dataGaLocation":493},{"text":284,"config":611},{"href":286,"dataGaName":24,"dataGaLocation":493},{"text":288,"config":613},{"href":290,"dataGaName":291,"dataGaLocation":493},{"text":293,"config":615},{"href":295,"dataGaName":296,"dataGaLocation":493},{"text":298,"config":617},{"href":300,"dataGaName":301,"dataGaLocation":493},{"title":316,"links":619},[620,622,624,626,628,630,632,636,641,643,645,647],{"text":323,"config":621},{"href":325,"dataGaName":318,"dataGaLocation":493},{"text":328,"config":623},{"href":330,"dataGaName":331,"dataGaLocation":493},{"text":336,"config":625},{"href":338,"dataGaName":339,"dataGaLocation":493},{"text":341,"config":627},{"href":343,"dataGaName":344,"dataGaLocation":493},{"text":346,"config":629},{"href":348,"dataGaName":349,"dataGaLocation":493},{"text":351,"config":631},{"href":353,"dataGaName":354,"dataGaLocation":493},{"text":633,"config":634},"Sustainability",{"href":635,"dataGaName":633,"dataGaLocation":493},"/sustainability/",{"text":637,"config":638},"Diversity, inclusion and belonging (DIB)",{"href":639,"dataGaName":640,"dataGaLocation":493},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":356,"config":642},{"href":358,"dataGaName":359,"dataGaLocation":493},{"text":366,"config":644},{"href":368,"dataGaName":369,"dataGaLocation":493},{"text":371,"config":646},{"href":373,"dataGaName":374,"dataGaLocation":493},{"text":648,"config":649},"Modern Slavery Transparency Statement",{"href":650,"dataGaName":651,"dataGaLocation":493},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":653,"links":654},"Contact Us",[655,658,660,662,667,672,677],{"text":656,"config":657},"Contact an expert",{"href":57,"dataGaName":58,"dataGaLocation":493},{"text":385,"config":659},{"href":387,"dataGaName":388,"dataGaLocation":493},{"text":390,"config":661},{"href":392,"dataGaName":393,"dataGaLocation":493},{"text":663,"config":664},"Status",{"href":665,"dataGaName":666,"dataGaLocation":493},"https://status.gitlab.com/","status",{"text":668,"config":669},"Terms of use",{"href":670,"dataGaName":671,"dataGaLocation":493},"/terms/","terms of use",{"text":673,"config":674},"Privacy statement",{"href":675,"dataGaName":676,"dataGaLocation":493},"/privacy/","privacy statement",{"text":678,"config":679},"Cookie preferences",{"dataGaName":680,"dataGaLocation":493,"id":681,"isOneTrustButton":111},"cookie preferences","ot-sdk-btn",{"items":683},[684,686,688],{"text":668,"config":685},{"href":670,"dataGaName":671,"dataGaLocation":493},{"text":673,"config":687},{"href":675,"dataGaName":676,"dataGaLocation":493},{"text":678,"config":689},{"dataGaName":680,"dataGaLocation":493,"id":681,"isOneTrustButton":111},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[695],{"_path":696,"_dir":697,"_draft":6,"_partial":6,"_locale":7,"content":698,"config":702,"_id":704,"_type":34,"title":18,"_source":36,"_file":705,"_stem":706,"_extension":39},"/en-us/blog/authors/lee-tickett","authors",{"name":18,"config":699},{"headshot":700,"ctfId":701},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1752592356/ibeixykxeiey9aiebylt.png","leetickett",{"template":703},"BlogAuthor","content:en-us:blog:authors:lee-tickett.yml","en-us/blog/authors/lee-tickett.yml","en-us/blog/authors/lee-tickett",{"_path":708,"_dir":42,"_draft":6,"_partial":6,"_locale":7,"header":709,"eyebrow":710,"blurb":711,"button":712,"secondaryButton":716,"_id":718,"_type":34,"title":719,"_source":36,"_file":720,"_stem":721,"_extension":39},"/shared/en-us/next-steps","Start shipping better software faster","50%+ of the Fortune 100 trust GitLab","See what your team can do with the intelligent\n\n\nDevSecOps platform.\n",{"text":50,"config":713},{"href":714,"dataGaName":53,"dataGaLocation":715},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":55,"config":717},{"href":57,"dataGaName":58,"dataGaLocation":715},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1758653942934]