[{"data":1,"prerenderedAt":2879},["ShallowReactive",2],{"/blog/can-chatgpt-resolve-gitlab-issues":3,"navigation-en-us":2082,"banner-en-us":2508,"footer-en-us":2518,"blog-post-authors-en-us-John Coghlan|Fatima Sarah Khalid":2762,"blog-related-posts-en-us-can-chatgpt-resolve-gitlab-issues":2789,"blog-promotions-en-us":2815,"next-steps-en-us":2869},{"id":4,"title":5,"authors":6,"body":9,"category":2060,"date":2061,"description":2062,"extension":2063,"externalUrl":2064,"faq":2064,"featured":2065,"heroImage":2066,"meta":2067,"navigation":378,"path":2068,"seo":2069,"slug":2073,"stem":2074,"tags":2075,"template":2080,"updatedDate":2064,"__hash__":2081},"blogPosts/en-us/blog/can-chatgpt-resolve-gitlab-issues.md","Testing ChatGPT: Can it solve a GitLab issue?",[7,8],"John Coghlan","Fatima Sarah Khalid",{"type":10,"value":11,"toc":2052},"minimark",[12,23,32,35,54,69,72,77,86,89,124,133,138,146,160,163,177,180,472,481,484,493,1184,1256,1259,1263,1284,1291,1300,1944,1949,1957,1960,1974,1983,1987,1993,2014,2029,2033,2042,2045,2048],[13,14,15,16,22],"p",{},"ChatGPT has taken the tech world by storm since its ",[17,18,21],"a",{"href":19,"rel":20},"https://openai.com/blog/chatgpt/",[],"launch on November 30",". Media coverage, front page posts on Hacker News, Twitter threads, and videos - everywhere you look, there is another story.",[13,24,25,26,31],{},"The ",[17,27,30],{"href":28,"rel":29},"https://handbook.gitlab.com/handbook/communication/#slack",[],"GitLab Slack"," was no different. In threads across Slack channels, including those for developer evangelism, UX, the CEO, random news, and every space in between, our team was chatting about this exciting new tool.",[13,33,34],{},"As we got more familiar with the tool, we started to learn about numerous things it can do. Here are a few that we found:",[36,37,38,42,45,48,51],"ul",{},[39,40,41],"li",{},"It can write poetry about GitLab features.",[39,43,44],{},"It can write blog posts.",[39,46,47],{},"It can write unit tests.",[39,49,50],{},"It gives advice on how to use certain features of GitLab.",[39,52,53],{},"It conducts competitive analysis.",[13,55,56,57,62,63,68],{},"There’s quite a bit more out there, including ",[17,58,61],{"href":59,"rel":60},"https://maximumeffort.substack.com/p/i-taught-chatgpt-to-invent-a-language",[],"inventing a new language"," and ",[17,64,67],{"href":65,"rel":66},"https://www.engraved.blog/building-a-virtual-machine-inside/",[],"building a virtual machine",". We can’t recall any technology that has generated more excitement in such a short time.",[13,70,71],{},"We acknowledge there are ethical and licensing concerns around using AI-generated code. For the purpose of this blog post, we will focus strictly on the capabilities of ChatGPT.",[73,74,76],"h2",{"id":75},"testing-chatgpt","Testing ChatGPT",[13,78,79,80,85],{},"As members of GitLab’s ",[17,81,84],{"href":82,"rel":83},"https://handbook.gitlab.com/handbook/marketing/developer-relations/",[],"Developer Relations team",", where we’re focused on growing our community of contributors and evangelists, our first reaction was to think of how this tool can help our contributors. The responses to questions like “How can I get started contributing to GitLab?” were cool but didn’t move the needle. So then we asked ourselves: Can we use ChatGPT to make a contribution to GitLab?",[13,87,88],{},"Having already been testing the tool, we knew we’d need to look for a very specific type of issue. We started to fine-tune our search. Here are the steps we took to find a potential issue:",[36,90,91,104,113],{},[39,92,93,94,98,99,103],{},"Visited ",[17,95,96],{"href":96,"rel":97},"https://gitlab.com/gitlab-org",[]," and pulled up all the open issues by clicking on ",[100,101,102],"code",{},"Issues"," in the left side nav.",[39,105,106,107,112],{},"Searched for all issues with the ",[17,108,111],{"href":109,"rel":110},"https://gitlab.com/gitlab-org/gitlab/-/issues/?sort=updated_desc&state=opened&label_name%5B%5D=good%20for%20new%20contributors&first_page_size=20",[],"“good for new contributors” label",". This returned 482 issues at the time of writing.",[39,114,115,116,123],{},"Set ",[17,117,120],{"href":118,"rel":119},"https://gitlab.com/gitlab-org/gitlab/-/issues/?sort=updated_desc&state=opened&label_name%5B%5D=good%20for%20new%20contributors&assignee_id=None&first_page_size=20",[],[100,121,122],{},"“Assignee = None”"," to filter out issues that have already been assigned to someone. This trimmed things down even more.",[13,125,126,127,132],{},"After poking through a few issues, this one caught our attention: an issue that is a request to ",[17,128,131],{"href":129,"rel":130},"https://gitlab.com/gitlab-org/gitlab/-/issues/221293",[],"de-depulicate identical dropdown functionality from two Vue components into a shared component",".",[134,135,137],"h3",{"id":136},"getting-started","Getting started",[13,139,140,141,145],{},"We opened up a ChatGPT thread via ",[17,142,143],{"href":143,"rel":144},"https://chat.openai.com/chat",[],". If you don’t already have an account, you’ll need to register with OpenAI.",[13,147,148,149,152,153,62,156,159],{},"Then we started a thread with Assistant (that’s what is returned when you ask ChatGPT what is its name). We asked Assistant to create a shared Vue component called ",[100,150,151],{},"SharedDropdownFilter"," from the duplicate code in ",[100,154,155],{},"GroupsDropdownFilter",[100,157,158],{},"ProjectsDropdownFilter"," and passed the scripts of both components.",[13,161,162],{},"ChatGPT replied with:",[164,165,166],"blockquote",{},[13,167,168,169,171,172,62,174,176],{},"You can create a new ",[100,170,151],{}," component that contains the duplicate code and use it in both ",[100,173,155],{},[100,175,158],{},":",[13,178,179],{},"and provided a template to describe the use. The template provided wasn’t quite what we were looking for.",[181,182,187],"pre",{"className":183,"code":184,"language":185,"meta":186,"style":186},"language-xml shiki shiki-themes github-light","\u003Ctemplate>\n  \u003CGlDropdown\n    :aria-label=\"label\"\n    :class=\"{ disabled: loading }\"\n    :disabled=\"loading\"\n    :selected=\"selectedProjectsLabel\"\n    :variant=\"multiSelect ? 'inline' : 'single-line'\"\n  >\n    \u003Ctemplate v-slot:menu>\n      \u003Cdiv class=\"py-4\">\n        \u003CGlSearchBoxByType\n          autofocus\n          class=\"search-box\"\n          :placeholder=\"searchPlaceholder\"\n          :type=\"searchType\"\n          v-model=\"searchTerm\"\n        />\n\n        \u003CGlDropdownHeader\n          v-if=\"selectedProjects.length && multiSelect\"\n          :class=\"{ 'd-none': !searchTerm }\"\n          class=\"js-dropdown-header\"\n        >\n          \u003Cspan>\n            {{ selectedProjectsLabel }}\n          \u003C/span>\n\n          \u003Cbutton\n\n","xml","",[100,188,189,205,214,228,239,250,261,272,278,289,308,317,323,334,345,356,367,373,380,388,406,417,427,433,443,449,459,464],{"__ignoreMap":186},[190,191,194,198,202],"span",{"class":192,"line":193},"line",1,[190,195,197],{"class":196},"sgsFI","\u003C",[190,199,201],{"class":200},"shJU0","template",[190,203,204],{"class":196},">\n",[190,206,208,211],{"class":192,"line":207},2,[190,209,210],{"class":196},"  \u003C",[190,212,213],{"class":200},"GlDropdown\n",[190,215,217,221,224],{"class":192,"line":216},3,[190,218,220],{"class":219},"s7eDp","    :aria-label",[190,222,223],{"class":196},"=",[190,225,227],{"class":226},"sYBdl","\"label\"\n",[190,229,231,234,236],{"class":192,"line":230},4,[190,232,233],{"class":219},"    :class",[190,235,223],{"class":196},[190,237,238],{"class":226},"\"{ disabled: loading }\"\n",[190,240,242,245,247],{"class":192,"line":241},5,[190,243,244],{"class":219},"    :disabled",[190,246,223],{"class":196},[190,248,249],{"class":226},"\"loading\"\n",[190,251,253,256,258],{"class":192,"line":252},6,[190,254,255],{"class":219},"    :selected",[190,257,223],{"class":196},[190,259,260],{"class":226},"\"selectedProjectsLabel\"\n",[190,262,264,267,269],{"class":192,"line":263},7,[190,265,266],{"class":219},"    :variant",[190,268,223],{"class":196},[190,270,271],{"class":226},"\"multiSelect ? 'inline' : 'single-line'\"\n",[190,273,275],{"class":192,"line":274},8,[190,276,277],{"class":196},"  >\n",[190,279,281,284,286],{"class":192,"line":280},9,[190,282,283],{"class":196},"    \u003C",[190,285,201],{"class":200},[190,287,288],{"class":196}," v-slot:menu>\n",[190,290,292,295,298,301,303,306],{"class":192,"line":291},10,[190,293,294],{"class":196},"      \u003C",[190,296,297],{"class":200},"div",[190,299,300],{"class":219}," class",[190,302,223],{"class":196},[190,304,305],{"class":226},"\"py-4\"",[190,307,204],{"class":196},[190,309,311,314],{"class":192,"line":310},11,[190,312,313],{"class":196},"        \u003C",[190,315,316],{"class":200},"GlSearchBoxByType\n",[190,318,320],{"class":192,"line":319},12,[190,321,322],{"class":196},"          autofocus\n",[190,324,326,329,331],{"class":192,"line":325},13,[190,327,328],{"class":219},"          class",[190,330,223],{"class":196},[190,332,333],{"class":226},"\"search-box\"\n",[190,335,337,340,342],{"class":192,"line":336},14,[190,338,339],{"class":219},"          :placeholder",[190,341,223],{"class":196},[190,343,344],{"class":226},"\"searchPlaceholder\"\n",[190,346,348,351,353],{"class":192,"line":347},15,[190,349,350],{"class":219},"          :type",[190,352,223],{"class":196},[190,354,355],{"class":226},"\"searchType\"\n",[190,357,359,362,364],{"class":192,"line":358},16,[190,360,361],{"class":219},"          v-model",[190,363,223],{"class":196},[190,365,366],{"class":226},"\"searchTerm\"\n",[190,368,370],{"class":192,"line":369},17,[190,371,372],{"class":196},"        />\n",[190,374,376],{"class":192,"line":375},18,[190,377,379],{"emptyLinePlaceholder":378},true,"\n",[190,381,383,385],{"class":192,"line":382},19,[190,384,313],{"class":196},[190,386,387],{"class":200},"GlDropdownHeader\n",[190,389,391,394,396,399,403],{"class":192,"line":390},20,[190,392,393],{"class":219},"          v-if",[190,395,223],{"class":196},[190,397,398],{"class":226},"\"selectedProjects.length ",[190,400,402],{"class":401},"sB1qb","&&",[190,404,405],{"class":226}," multiSelect\"\n",[190,407,409,412,414],{"class":192,"line":408},21,[190,410,411],{"class":219},"          :class",[190,413,223],{"class":196},[190,415,416],{"class":226},"\"{ 'd-none': !searchTerm }\"\n",[190,418,420,422,424],{"class":192,"line":419},22,[190,421,328],{"class":219},[190,423,223],{"class":196},[190,425,426],{"class":226},"\"js-dropdown-header\"\n",[190,428,430],{"class":192,"line":429},23,[190,431,432],{"class":196},"        >\n",[190,434,436,439,441],{"class":192,"line":435},24,[190,437,438],{"class":196},"          \u003C",[190,440,190],{"class":200},[190,442,204],{"class":196},[190,444,446],{"class":192,"line":445},25,[190,447,448],{"class":196},"            {{ selectedProjectsLabel }}\n",[190,450,452,455,457],{"class":192,"line":451},26,[190,453,454],{"class":196},"          \u003C/",[190,456,190],{"class":200},[190,458,204],{"class":196},[190,460,462],{"class":192,"line":461},27,[190,463,379],{"emptyLinePlaceholder":378},[190,465,467,469],{"class":192,"line":466},28,[190,468,438],{"class":196},[190,470,471],{"class":200},"button\n",[13,473,474,475,477,478,480],{},"So we tried again, this time being more specific and asking ChatGPT to “Create a shared Vue component that combines the two components ",[100,476,158],{}," and  ",[100,479,155],{},"”. We passed in the full component files, including the templates.",[13,482,483],{},"ChatGPT responded with instructions, a sample Vue component, and an explanation of the functionality:",[164,485,486],{},[13,487,488,489,62,491,176],{},"Here is a sample implementation of a shared Vue component that combines the two components ",[100,490,158],{},[100,492,155],{},[181,494,498],{"className":495,"code":496,"language":497,"meta":186,"style":186},"language-vue shiki shiki-themes github-light","\u003Ctemplate>\n  \u003Cdiv>\n    \u003CProjectsDropdownFilter\n      :groupId=\"groupId\"\n      :multiSelect=\"multiSelect\"\n      :label=\"label\"\n      :queryParams=\"queryParams\"\n      :defaultProjects=\"defaultProjects\"\n      @selected=\"onProjectsSelected\"\n    />\n    \u003CGroupsDropdownFilter\n      :multiSelect=\"multiSelect\"\n      :label=\"label\"\n      :queryParams=\"queryParams\"\n      :defaultGroups=\"defaultGroups\"\n      @selected=\"onGroupsSelected\"\n    />\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript>\nimport { ProjectsDropdownFilter } from './ProjectsDropdownFilter.vue';\nimport { GroupsDropdownFilter } from './GroupsDropdownFilter.vue';\n\nexport default {\n  name: 'SharedDropdownFilter',\n  components: {\n    ProjectsDropdownFilter,\n    GroupsDropdownFilter,\n  },\n  props: {\n    groupId: {\n      type: Number,\n      required: true,\n    },\n    multiSelect: {\n      type: Boolean,\n      required: false,\n      default: false,\n    },\n    label: {\n      type: String,\n      required: false,\n      default: 'Dropdown filter',\n    },\n    queryParams: {\n      type: Object,\n      required: false,\n      default: () => ({}),\n    },\n    defaultProjects: {\n      type: Array,\n      required: false,\n      default: () => [],\n    },\n    defaultGroups: {\n      type: Array,\n      required: false,\n      default: () => [],\n    },\n  },\n  data() {\n    return {\n      selectedProjects: this.defaultProjects || [],\n      selectedGroups: this.defaultGroups || [],\n    };\n  },\n  methods: {\n    onProjectsSelected(selectedProjects) {\n      this.selectedProjects = selectedProjects;\n      this.$emit('selected', this.selectedProjects, this.selectedGroups);\n    },\n    onGroupsSelected(selectedGroups) {\n      this.selectedGroups = selectedGroups;\n      this.$emit('selected', this.selectedProjects, this.selectedGroups);\n    },\n  },\n};\n\u003C/script>\n","vue",[100,499,500,508,516,523,533,543,552,562,572,582,587,594,602,610,618,628,637,641,650,659,663,672,690,704,708,719,730,735,740,746,752,758,764,770,782,788,794,800,810,820,825,831,837,846,856,861,867,873,882,897,902,908,914,923,935,940,946,951,960,971,976,981,990,998,1015,1030,1036,1041,1047,1063,1077,1105,1110,1123,1136,1159,1164,1169,1175],{"__ignoreMap":186},[190,501,502,504,506],{"class":192,"line":193},[190,503,197],{"class":196},[190,505,201],{"class":200},[190,507,204],{"class":196},[190,509,510,512,514],{"class":192,"line":207},[190,511,210],{"class":196},[190,513,297],{"class":200},[190,515,204],{"class":196},[190,517,518,520],{"class":192,"line":216},[190,519,283],{"class":196},[190,521,522],{"class":200},"ProjectsDropdownFilter\n",[190,524,525,528,530],{"class":192,"line":230},[190,526,527],{"class":219},"      :groupId",[190,529,223],{"class":196},[190,531,532],{"class":226},"\"groupId\"\n",[190,534,535,538,540],{"class":192,"line":241},[190,536,537],{"class":219},"      :multiSelect",[190,539,223],{"class":196},[190,541,542],{"class":226},"\"multiSelect\"\n",[190,544,545,548,550],{"class":192,"line":252},[190,546,547],{"class":219},"      :label",[190,549,223],{"class":196},[190,551,227],{"class":226},[190,553,554,557,559],{"class":192,"line":263},[190,555,556],{"class":219},"      :queryParams",[190,558,223],{"class":196},[190,560,561],{"class":226},"\"queryParams\"\n",[190,563,564,567,569],{"class":192,"line":274},[190,565,566],{"class":219},"      :defaultProjects",[190,568,223],{"class":196},[190,570,571],{"class":226},"\"defaultProjects\"\n",[190,573,574,577,579],{"class":192,"line":280},[190,575,576],{"class":219},"      @selected",[190,578,223],{"class":196},[190,580,581],{"class":226},"\"onProjectsSelected\"\n",[190,583,584],{"class":192,"line":291},[190,585,586],{"class":196},"    />\n",[190,588,589,591],{"class":192,"line":310},[190,590,283],{"class":196},[190,592,593],{"class":200},"GroupsDropdownFilter\n",[190,595,596,598,600],{"class":192,"line":319},[190,597,537],{"class":219},[190,599,223],{"class":196},[190,601,542],{"class":226},[190,603,604,606,608],{"class":192,"line":325},[190,605,547],{"class":219},[190,607,223],{"class":196},[190,609,227],{"class":226},[190,611,612,614,616],{"class":192,"line":336},[190,613,556],{"class":219},[190,615,223],{"class":196},[190,617,561],{"class":226},[190,619,620,623,625],{"class":192,"line":347},[190,621,622],{"class":219},"      :defaultGroups",[190,624,223],{"class":196},[190,626,627],{"class":226},"\"defaultGroups\"\n",[190,629,630,632,634],{"class":192,"line":358},[190,631,576],{"class":219},[190,633,223],{"class":196},[190,635,636],{"class":226},"\"onGroupsSelected\"\n",[190,638,639],{"class":192,"line":369},[190,640,586],{"class":196},[190,642,643,646,648],{"class":192,"line":375},[190,644,645],{"class":196},"  \u003C/",[190,647,297],{"class":200},[190,649,204],{"class":196},[190,651,652,655,657],{"class":192,"line":382},[190,653,654],{"class":196},"\u003C/",[190,656,201],{"class":200},[190,658,204],{"class":196},[190,660,661],{"class":192,"line":390},[190,662,379],{"emptyLinePlaceholder":378},[190,664,665,667,670],{"class":192,"line":408},[190,666,197],{"class":196},[190,668,669],{"class":200},"script",[190,671,204],{"class":196},[190,673,674,678,681,684,687],{"class":192,"line":419},[190,675,677],{"class":676},"sD7c4","import",[190,679,680],{"class":196}," { ProjectsDropdownFilter } ",[190,682,683],{"class":676},"from",[190,685,686],{"class":226}," './ProjectsDropdownFilter.vue'",[190,688,689],{"class":196},";\n",[190,691,692,694,697,699,702],{"class":192,"line":429},[190,693,677],{"class":676},[190,695,696],{"class":196}," { GroupsDropdownFilter } ",[190,698,683],{"class":676},[190,700,701],{"class":226}," './GroupsDropdownFilter.vue'",[190,703,689],{"class":196},[190,705,706],{"class":192,"line":435},[190,707,379],{"emptyLinePlaceholder":378},[190,709,710,713,716],{"class":192,"line":445},[190,711,712],{"class":676},"export",[190,714,715],{"class":676}," default",[190,717,718],{"class":196}," {\n",[190,720,721,724,727],{"class":192,"line":451},[190,722,723],{"class":196},"  name: ",[190,725,726],{"class":226},"'SharedDropdownFilter'",[190,728,729],{"class":196},",\n",[190,731,732],{"class":192,"line":461},[190,733,734],{"class":196},"  components: {\n",[190,736,737],{"class":192,"line":466},[190,738,739],{"class":196},"    ProjectsDropdownFilter,\n",[190,741,743],{"class":192,"line":742},29,[190,744,745],{"class":196},"    GroupsDropdownFilter,\n",[190,747,749],{"class":192,"line":748},30,[190,750,751],{"class":196},"  },\n",[190,753,755],{"class":192,"line":754},31,[190,756,757],{"class":196},"  props: {\n",[190,759,761],{"class":192,"line":760},32,[190,762,763],{"class":196},"    groupId: {\n",[190,765,767],{"class":192,"line":766},33,[190,768,769],{"class":196},"      type: Number,\n",[190,771,773,776,780],{"class":192,"line":772},34,[190,774,775],{"class":196},"      required: ",[190,777,779],{"class":778},"sYu0t","true",[190,781,729],{"class":196},[190,783,785],{"class":192,"line":784},35,[190,786,787],{"class":196},"    },\n",[190,789,791],{"class":192,"line":790},36,[190,792,793],{"class":196},"    multiSelect: {\n",[190,795,797],{"class":192,"line":796},37,[190,798,799],{"class":196},"      type: Boolean,\n",[190,801,803,805,808],{"class":192,"line":802},38,[190,804,775],{"class":196},[190,806,807],{"class":778},"false",[190,809,729],{"class":196},[190,811,813,816,818],{"class":192,"line":812},39,[190,814,815],{"class":196},"      default: ",[190,817,807],{"class":778},[190,819,729],{"class":196},[190,821,823],{"class":192,"line":822},40,[190,824,787],{"class":196},[190,826,828],{"class":192,"line":827},41,[190,829,830],{"class":196},"    label: {\n",[190,832,834],{"class":192,"line":833},42,[190,835,836],{"class":196},"      type: String,\n",[190,838,840,842,844],{"class":192,"line":839},43,[190,841,775],{"class":196},[190,843,807],{"class":778},[190,845,729],{"class":196},[190,847,849,851,854],{"class":192,"line":848},44,[190,850,815],{"class":196},[190,852,853],{"class":226},"'Dropdown filter'",[190,855,729],{"class":196},[190,857,859],{"class":192,"line":858},45,[190,860,787],{"class":196},[190,862,864],{"class":192,"line":863},46,[190,865,866],{"class":196},"    queryParams: {\n",[190,868,870],{"class":192,"line":869},47,[190,871,872],{"class":196},"      type: Object,\n",[190,874,876,878,880],{"class":192,"line":875},48,[190,877,775],{"class":196},[190,879,807],{"class":778},[190,881,729],{"class":196},[190,883,885,888,891,894],{"class":192,"line":884},49,[190,886,887],{"class":219},"      default",[190,889,890],{"class":196},": () ",[190,892,893],{"class":676},"=>",[190,895,896],{"class":196}," ({}),\n",[190,898,900],{"class":192,"line":899},50,[190,901,787],{"class":196},[190,903,905],{"class":192,"line":904},51,[190,906,907],{"class":196},"    defaultProjects: {\n",[190,909,911],{"class":192,"line":910},52,[190,912,913],{"class":196},"      type: Array,\n",[190,915,917,919,921],{"class":192,"line":916},53,[190,918,775],{"class":196},[190,920,807],{"class":778},[190,922,729],{"class":196},[190,924,926,928,930,932],{"class":192,"line":925},54,[190,927,887],{"class":219},[190,929,890],{"class":196},[190,931,893],{"class":676},[190,933,934],{"class":196}," [],\n",[190,936,938],{"class":192,"line":937},55,[190,939,787],{"class":196},[190,941,943],{"class":192,"line":942},56,[190,944,945],{"class":196},"    defaultGroups: {\n",[190,947,949],{"class":192,"line":948},57,[190,950,913],{"class":196},[190,952,954,956,958],{"class":192,"line":953},58,[190,955,775],{"class":196},[190,957,807],{"class":778},[190,959,729],{"class":196},[190,961,963,965,967,969],{"class":192,"line":962},59,[190,964,887],{"class":219},[190,966,890],{"class":196},[190,968,893],{"class":676},[190,970,934],{"class":196},[190,972,974],{"class":192,"line":973},60,[190,975,787],{"class":196},[190,977,979],{"class":192,"line":978},61,[190,980,751],{"class":196},[190,982,984,987],{"class":192,"line":983},62,[190,985,986],{"class":219},"  data",[190,988,989],{"class":196},"() {\n",[190,991,993,996],{"class":192,"line":992},63,[190,994,995],{"class":676},"    return",[190,997,718],{"class":196},[190,999,1001,1004,1007,1010,1013],{"class":192,"line":1000},64,[190,1002,1003],{"class":196},"      selectedProjects: ",[190,1005,1006],{"class":778},"this",[190,1008,1009],{"class":196},".defaultProjects ",[190,1011,1012],{"class":676},"||",[190,1014,934],{"class":196},[190,1016,1018,1021,1023,1026,1028],{"class":192,"line":1017},65,[190,1019,1020],{"class":196},"      selectedGroups: ",[190,1022,1006],{"class":778},[190,1024,1025],{"class":196},".defaultGroups ",[190,1027,1012],{"class":676},[190,1029,934],{"class":196},[190,1031,1033],{"class":192,"line":1032},66,[190,1034,1035],{"class":196},"    };\n",[190,1037,1039],{"class":192,"line":1038},67,[190,1040,751],{"class":196},[190,1042,1044],{"class":192,"line":1043},68,[190,1045,1046],{"class":196},"  methods: {\n",[190,1048,1050,1053,1056,1060],{"class":192,"line":1049},69,[190,1051,1052],{"class":219},"    onProjectsSelected",[190,1054,1055],{"class":196},"(",[190,1057,1059],{"class":1058},"sqxcx","selectedProjects",[190,1061,1062],{"class":196},") {\n",[190,1064,1066,1069,1072,1074],{"class":192,"line":1065},70,[190,1067,1068],{"class":778},"      this",[190,1070,1071],{"class":196},".selectedProjects ",[190,1073,223],{"class":676},[190,1075,1076],{"class":196}," selectedProjects;\n",[190,1078,1080,1082,1084,1087,1089,1092,1095,1097,1100,1102],{"class":192,"line":1079},71,[190,1081,1068],{"class":778},[190,1083,132],{"class":196},[190,1085,1086],{"class":219},"$emit",[190,1088,1055],{"class":196},[190,1090,1091],{"class":226},"'selected'",[190,1093,1094],{"class":196},", ",[190,1096,1006],{"class":778},[190,1098,1099],{"class":196},".selectedProjects, ",[190,1101,1006],{"class":778},[190,1103,1104],{"class":196},".selectedGroups);\n",[190,1106,1108],{"class":192,"line":1107},72,[190,1109,787],{"class":196},[190,1111,1113,1116,1118,1121],{"class":192,"line":1112},73,[190,1114,1115],{"class":219},"    onGroupsSelected",[190,1117,1055],{"class":196},[190,1119,1120],{"class":1058},"selectedGroups",[190,1122,1062],{"class":196},[190,1124,1126,1128,1131,1133],{"class":192,"line":1125},74,[190,1127,1068],{"class":778},[190,1129,1130],{"class":196},".selectedGroups ",[190,1132,223],{"class":676},[190,1134,1135],{"class":196}," selectedGroups;\n",[190,1137,1139,1141,1143,1145,1147,1149,1151,1153,1155,1157],{"class":192,"line":1138},75,[190,1140,1068],{"class":778},[190,1142,132],{"class":196},[190,1144,1086],{"class":219},[190,1146,1055],{"class":196},[190,1148,1091],{"class":226},[190,1150,1094],{"class":196},[190,1152,1006],{"class":778},[190,1154,1099],{"class":196},[190,1156,1006],{"class":778},[190,1158,1104],{"class":196},[190,1160,1162],{"class":192,"line":1161},76,[190,1163,787],{"class":196},[190,1165,1167],{"class":192,"line":1166},77,[190,1168,751],{"class":196},[190,1170,1172],{"class":192,"line":1171},78,[190,1173,1174],{"class":196},"};\n",[190,1176,1178,1180,1182],{"class":192,"line":1177},79,[190,1179,654],{"class":196},[190,1181,669],{"class":200},[190,1183,204],{"class":196},[164,1185,1186],{},[13,1187,1188,1189,1191,1192,1194,1195,1198,1199,1094,1202,1094,1205,1094,1208,1211,1212,1215,1216,1218,1219,1094,1221,1094,1223,1211,1225,1215,1228,1230,1231,62,1233,1235,1236,1238,1239,1242,1243,62,1245,1247,1248,62,1250,1252,1253,1255],{},"In this implementation, the ",[100,1190,151],{}," component is rendered as a container for the ",[100,1193,158],{}," and",[100,1196,1197],{}," GroupsDropdownFilter"," components. It passes down the ",[100,1200,1201],{},"groupId",[100,1203,1204],{},"multiSelect",[100,1206,1207],{},"label",[100,1209,1210],{},"queryParams",", and ",[100,1213,1214],{},"defaultProjects"," props to the ",[100,1217,158],{}," component, and the ",[100,1220,1204],{},[100,1222,1207],{},[100,1224,1210],{},[100,1226,1227],{},"defaultGroups",[100,1229,155],{}," component. It also listens to the selected event emitted by the two components and updates its own ",[100,1232,1059],{},[100,1234,1120],{}," data accordingly. The ",[100,1237,151],{}," component emits its own ",[100,1240,1241],{},"selected"," event with the updated ",[100,1244,1059],{},[100,1246,1120],{}," data when it receives the selected event from the ",[100,1249,158],{},[100,1251,155],{}," components. This allows the parent component of the ",[100,1254,151],{}," to be notified whenever the selected projects and groups are updated, so that it can take appropriate action, such as updating the data it displays.",[13,1257,1258],{},"With ChatGPT’s shared Vue component, we could start an MR for the issue, but would need to manually review the code and run tests in order to make sure the deduplication was done correctly.",[134,1260,1262],{"id":1261},"adjusting-the-filters","Adjusting the filters",[13,1264,1265,1266,62,1269,1272,1273,1278,1279,132],{},"In hopes of finding an issue that ChatGPT could fully solve, this time we filtered using two labels (",[100,1267,1268],{},"good for new contributors",[100,1270,1271],{},"quick win","), Assignee = None, and added the keyword “refactor” to look for issues that required less net new code. At the time of writing, this ",[17,1274,1277],{"href":1275,"rel":1276},"https://gitlab.com/gitlab-org/gitlab/-/issues/?search=refactor&sort=updated_asc&state=opened&label_name%5B%5D=quick%20win&label_name%5B%5D=good%20for%20new%20contributors&assignee_id=None&first_page_size=20",[],"query"," returned one issue: ",[17,1280,1283],{"href":1281,"rel":1282},"https://gitlab.com/gitlab-org/gitlab/-/issues/228611",[],"a refactor for widget state tests",[13,1285,1286,1287,1290],{},"After reviewing the issue, we opened the ",[100,1288,1289],{},"/spec/frontend/vue_merge_request_widget/stores/get_state_key_spec.js"," file mentioned in the issue description by navigating to that file on GitLab.com SaaS and opening the dropdown on the blue button at the top of the file frame, selecting “Open in Web IDE”, and then clicking the button to open the file in GitLab’s built-in Web IDE.",[13,1292,1293,1294,1297,1298,176],{},"We copied the code from the file and asked ChatGPT to refactor these tests into a table of ",[100,1295,1296],{},"it.each",". It was interesting to watch the output as ChatGPT provided an example of how we could refactor the tests using ",[100,1299,1296],{},[181,1301,1305],{"className":1302,"code":1303,"language":1304,"meta":186,"style":186},"language-javascript shiki shiki-themes github-light","import getStateKey from '~/vue_merge_request_widget/stores/get_state_key';\n\ndescribe('getStateKey', () => {\n  const context = {\n    mergeStatus: 'checked',\n    autoMergeEnabled: false,\n    canMerge: true,\n    onlyAllowMergeIfPipelineSucceeds: false,\n    isPipelineFailed: false,\n    hasMergeableDiscussionsState: false,\n    isPipelineBlocked: false,\n    canBeMerged: false,\n    projectArchived: false,\n    branchMissing: false,\n    commitsCount: 2,\n    hasConflicts: false,\n    draft: false,\n    detailedMergeStatus: null,\n  };\n\n  it.each([\n    [{}, null],\n    [{detailedMergeStatus: 'MERGEABLE'}, 'readyToMerge'],\n    [{detailedMergeStatus: 'DISCUSSIONS_NOT_RESOLVED'}, 'unresolvedDiscussions'],\n    [{detailedMergeStatus: 'DRAFT_STATUS'}, 'draft'],\n    [{detailedMergeStatus: 'CI_MUST_PASS'}, 'pipelineFailed'],\n    [{shouldBeRebased: true}, 'rebase'],\n    [{hasConflicts: true}, 'conflicts'],\n    [{detailedMergeStatus: 'CHECKING'}, 'checking'],\n    [{commitsCount: 0}, 'nothingToMerge'],\n    [{commitsCount: 1, branchMissing: true}, 'missingBranch'],\n    [{projectArchived: true}, 'archived'],\n  ])('should return \"%s\" when called with %p', (expected, input) => {\n    const bound = getStateKey.bind(Object.assign({}, context, input));\n    expect(bound()).toEqual(expected);\n  });\n\n  it('returns rebased state key', () => {\n    const context = {\n      mergeStatus: 'checked',\n      autoMergeEnabled: false,\n      canMerge: true,\n      onlyAllowMergeIfPipelineSucceeds: true,\n      isPipelineFailed: true,\n      hasMergeableDiscussionsState: false,\n      isPipelineBlocked: false,\n      canBeMerged: false,\n      shouldBeRebased: true,\n      projectArchived: false,\n      branchMissing: false,\n      commitsCount: 2,\n      hasConflicts: false,\n      draft: false,\n    };\n    const bound = getStateKey.bind(context);\n\n    expect(bound()).toEqual('rebase');\n  });\n});\n","javascript",[100,1306,1307,1321,1325,1342,1355,1365,1374,1383,1392,1401,1410,1419,1428,1437,1446,1456,1465,1474,1484,1489,1493,1504,1514,1530,1544,1558,1572,1586,1600,1614,1629,1648,1662,1688,1713,1732,1737,1741,1757,1767,1776,1785,1794,1803,1812,1821,1830,1839,1848,1857,1866,1875,1884,1893,1897,1912,1916,1935,1939],{"__ignoreMap":186},[190,1308,1309,1311,1314,1316,1319],{"class":192,"line":193},[190,1310,677],{"class":676},[190,1312,1313],{"class":196}," getStateKey ",[190,1315,683],{"class":676},[190,1317,1318],{"class":226}," '~/vue_merge_request_widget/stores/get_state_key'",[190,1320,689],{"class":196},[190,1322,1323],{"class":192,"line":207},[190,1324,379],{"emptyLinePlaceholder":378},[190,1326,1327,1330,1332,1335,1338,1340],{"class":192,"line":216},[190,1328,1329],{"class":219},"describe",[190,1331,1055],{"class":196},[190,1333,1334],{"class":226},"'getStateKey'",[190,1336,1337],{"class":196},", () ",[190,1339,893],{"class":676},[190,1341,718],{"class":196},[190,1343,1344,1347,1350,1353],{"class":192,"line":230},[190,1345,1346],{"class":676},"  const",[190,1348,1349],{"class":778}," context",[190,1351,1352],{"class":676}," =",[190,1354,718],{"class":196},[190,1356,1357,1360,1363],{"class":192,"line":241},[190,1358,1359],{"class":196},"    mergeStatus: ",[190,1361,1362],{"class":226},"'checked'",[190,1364,729],{"class":196},[190,1366,1367,1370,1372],{"class":192,"line":252},[190,1368,1369],{"class":196},"    autoMergeEnabled: ",[190,1371,807],{"class":778},[190,1373,729],{"class":196},[190,1375,1376,1379,1381],{"class":192,"line":263},[190,1377,1378],{"class":196},"    canMerge: ",[190,1380,779],{"class":778},[190,1382,729],{"class":196},[190,1384,1385,1388,1390],{"class":192,"line":274},[190,1386,1387],{"class":196},"    onlyAllowMergeIfPipelineSucceeds: ",[190,1389,807],{"class":778},[190,1391,729],{"class":196},[190,1393,1394,1397,1399],{"class":192,"line":280},[190,1395,1396],{"class":196},"    isPipelineFailed: ",[190,1398,807],{"class":778},[190,1400,729],{"class":196},[190,1402,1403,1406,1408],{"class":192,"line":291},[190,1404,1405],{"class":196},"    hasMergeableDiscussionsState: ",[190,1407,807],{"class":778},[190,1409,729],{"class":196},[190,1411,1412,1415,1417],{"class":192,"line":310},[190,1413,1414],{"class":196},"    isPipelineBlocked: ",[190,1416,807],{"class":778},[190,1418,729],{"class":196},[190,1420,1421,1424,1426],{"class":192,"line":319},[190,1422,1423],{"class":196},"    canBeMerged: ",[190,1425,807],{"class":778},[190,1427,729],{"class":196},[190,1429,1430,1433,1435],{"class":192,"line":325},[190,1431,1432],{"class":196},"    projectArchived: ",[190,1434,807],{"class":778},[190,1436,729],{"class":196},[190,1438,1439,1442,1444],{"class":192,"line":336},[190,1440,1441],{"class":196},"    branchMissing: ",[190,1443,807],{"class":778},[190,1445,729],{"class":196},[190,1447,1448,1451,1454],{"class":192,"line":347},[190,1449,1450],{"class":196},"    commitsCount: ",[190,1452,1453],{"class":778},"2",[190,1455,729],{"class":196},[190,1457,1458,1461,1463],{"class":192,"line":358},[190,1459,1460],{"class":196},"    hasConflicts: ",[190,1462,807],{"class":778},[190,1464,729],{"class":196},[190,1466,1467,1470,1472],{"class":192,"line":369},[190,1468,1469],{"class":196},"    draft: ",[190,1471,807],{"class":778},[190,1473,729],{"class":196},[190,1475,1476,1479,1482],{"class":192,"line":375},[190,1477,1478],{"class":196},"    detailedMergeStatus: ",[190,1480,1481],{"class":778},"null",[190,1483,729],{"class":196},[190,1485,1486],{"class":192,"line":382},[190,1487,1488],{"class":196},"  };\n",[190,1490,1491],{"class":192,"line":390},[190,1492,379],{"emptyLinePlaceholder":378},[190,1494,1495,1498,1501],{"class":192,"line":408},[190,1496,1497],{"class":196},"  it.",[190,1499,1500],{"class":219},"each",[190,1502,1503],{"class":196},"([\n",[190,1505,1506,1509,1511],{"class":192,"line":419},[190,1507,1508],{"class":196},"    [{}, ",[190,1510,1481],{"class":778},[190,1512,1513],{"class":196},"],\n",[190,1515,1516,1519,1522,1525,1528],{"class":192,"line":429},[190,1517,1518],{"class":196},"    [{detailedMergeStatus: ",[190,1520,1521],{"class":226},"'MERGEABLE'",[190,1523,1524],{"class":196},"}, ",[190,1526,1527],{"class":226},"'readyToMerge'",[190,1529,1513],{"class":196},[190,1531,1532,1534,1537,1539,1542],{"class":192,"line":435},[190,1533,1518],{"class":196},[190,1535,1536],{"class":226},"'DISCUSSIONS_NOT_RESOLVED'",[190,1538,1524],{"class":196},[190,1540,1541],{"class":226},"'unresolvedDiscussions'",[190,1543,1513],{"class":196},[190,1545,1546,1548,1551,1553,1556],{"class":192,"line":445},[190,1547,1518],{"class":196},[190,1549,1550],{"class":226},"'DRAFT_STATUS'",[190,1552,1524],{"class":196},[190,1554,1555],{"class":226},"'draft'",[190,1557,1513],{"class":196},[190,1559,1560,1562,1565,1567,1570],{"class":192,"line":451},[190,1561,1518],{"class":196},[190,1563,1564],{"class":226},"'CI_MUST_PASS'",[190,1566,1524],{"class":196},[190,1568,1569],{"class":226},"'pipelineFailed'",[190,1571,1513],{"class":196},[190,1573,1574,1577,1579,1581,1584],{"class":192,"line":461},[190,1575,1576],{"class":196},"    [{shouldBeRebased: ",[190,1578,779],{"class":778},[190,1580,1524],{"class":196},[190,1582,1583],{"class":226},"'rebase'",[190,1585,1513],{"class":196},[190,1587,1588,1591,1593,1595,1598],{"class":192,"line":466},[190,1589,1590],{"class":196},"    [{hasConflicts: ",[190,1592,779],{"class":778},[190,1594,1524],{"class":196},[190,1596,1597],{"class":226},"'conflicts'",[190,1599,1513],{"class":196},[190,1601,1602,1604,1607,1609,1612],{"class":192,"line":742},[190,1603,1518],{"class":196},[190,1605,1606],{"class":226},"'CHECKING'",[190,1608,1524],{"class":196},[190,1610,1611],{"class":226},"'checking'",[190,1613,1513],{"class":196},[190,1615,1616,1619,1622,1624,1627],{"class":192,"line":748},[190,1617,1618],{"class":196},"    [{commitsCount: ",[190,1620,1621],{"class":778},"0",[190,1623,1524],{"class":196},[190,1625,1626],{"class":226},"'nothingToMerge'",[190,1628,1513],{"class":196},[190,1630,1631,1633,1636,1639,1641,1643,1646],{"class":192,"line":754},[190,1632,1618],{"class":196},[190,1634,1635],{"class":778},"1",[190,1637,1638],{"class":196},", branchMissing: ",[190,1640,779],{"class":778},[190,1642,1524],{"class":196},[190,1644,1645],{"class":226},"'missingBranch'",[190,1647,1513],{"class":196},[190,1649,1650,1653,1655,1657,1660],{"class":192,"line":760},[190,1651,1652],{"class":196},"    [{projectArchived: ",[190,1654,779],{"class":778},[190,1656,1524],{"class":196},[190,1658,1659],{"class":226},"'archived'",[190,1661,1513],{"class":196},[190,1663,1664,1667,1670,1673,1676,1678,1681,1684,1686],{"class":192,"line":766},[190,1665,1666],{"class":196},"  ])(",[190,1668,1669],{"class":226},"'should return \"%s\" when called with %p'",[190,1671,1672],{"class":196},", (",[190,1674,1675],{"class":1058},"expected",[190,1677,1094],{"class":196},[190,1679,1680],{"class":1058},"input",[190,1682,1683],{"class":196},") ",[190,1685,893],{"class":676},[190,1687,718],{"class":196},[190,1689,1690,1693,1696,1698,1701,1704,1707,1710],{"class":192,"line":772},[190,1691,1692],{"class":676},"    const",[190,1694,1695],{"class":778}," bound",[190,1697,1352],{"class":676},[190,1699,1700],{"class":196}," getStateKey.",[190,1702,1703],{"class":219},"bind",[190,1705,1706],{"class":196},"(Object.",[190,1708,1709],{"class":219},"assign",[190,1711,1712],{"class":196},"({}, context, input));\n",[190,1714,1715,1718,1720,1723,1726,1729],{"class":192,"line":784},[190,1716,1717],{"class":219},"    expect",[190,1719,1055],{"class":196},[190,1721,1722],{"class":219},"bound",[190,1724,1725],{"class":196},"()).",[190,1727,1728],{"class":219},"toEqual",[190,1730,1731],{"class":196},"(expected);\n",[190,1733,1734],{"class":192,"line":790},[190,1735,1736],{"class":196},"  });\n",[190,1738,1739],{"class":192,"line":796},[190,1740,379],{"emptyLinePlaceholder":378},[190,1742,1743,1746,1748,1751,1753,1755],{"class":192,"line":802},[190,1744,1745],{"class":219},"  it",[190,1747,1055],{"class":196},[190,1749,1750],{"class":226},"'returns rebased state key'",[190,1752,1337],{"class":196},[190,1754,893],{"class":676},[190,1756,718],{"class":196},[190,1758,1759,1761,1763,1765],{"class":192,"line":812},[190,1760,1692],{"class":676},[190,1762,1349],{"class":778},[190,1764,1352],{"class":676},[190,1766,718],{"class":196},[190,1768,1769,1772,1774],{"class":192,"line":822},[190,1770,1771],{"class":196},"      mergeStatus: ",[190,1773,1362],{"class":226},[190,1775,729],{"class":196},[190,1777,1778,1781,1783],{"class":192,"line":827},[190,1779,1780],{"class":196},"      autoMergeEnabled: ",[190,1782,807],{"class":778},[190,1784,729],{"class":196},[190,1786,1787,1790,1792],{"class":192,"line":833},[190,1788,1789],{"class":196},"      canMerge: ",[190,1791,779],{"class":778},[190,1793,729],{"class":196},[190,1795,1796,1799,1801],{"class":192,"line":839},[190,1797,1798],{"class":196},"      onlyAllowMergeIfPipelineSucceeds: ",[190,1800,779],{"class":778},[190,1802,729],{"class":196},[190,1804,1805,1808,1810],{"class":192,"line":848},[190,1806,1807],{"class":196},"      isPipelineFailed: ",[190,1809,779],{"class":778},[190,1811,729],{"class":196},[190,1813,1814,1817,1819],{"class":192,"line":858},[190,1815,1816],{"class":196},"      hasMergeableDiscussionsState: ",[190,1818,807],{"class":778},[190,1820,729],{"class":196},[190,1822,1823,1826,1828],{"class":192,"line":863},[190,1824,1825],{"class":196},"      isPipelineBlocked: ",[190,1827,807],{"class":778},[190,1829,729],{"class":196},[190,1831,1832,1835,1837],{"class":192,"line":869},[190,1833,1834],{"class":196},"      canBeMerged: ",[190,1836,807],{"class":778},[190,1838,729],{"class":196},[190,1840,1841,1844,1846],{"class":192,"line":875},[190,1842,1843],{"class":196},"      shouldBeRebased: ",[190,1845,779],{"class":778},[190,1847,729],{"class":196},[190,1849,1850,1853,1855],{"class":192,"line":884},[190,1851,1852],{"class":196},"      projectArchived: ",[190,1854,807],{"class":778},[190,1856,729],{"class":196},[190,1858,1859,1862,1864],{"class":192,"line":899},[190,1860,1861],{"class":196},"      branchMissing: ",[190,1863,807],{"class":778},[190,1865,729],{"class":196},[190,1867,1868,1871,1873],{"class":192,"line":904},[190,1869,1870],{"class":196},"      commitsCount: ",[190,1872,1453],{"class":778},[190,1874,729],{"class":196},[190,1876,1877,1880,1882],{"class":192,"line":910},[190,1878,1879],{"class":196},"      hasConflicts: ",[190,1881,807],{"class":778},[190,1883,729],{"class":196},[190,1885,1886,1889,1891],{"class":192,"line":916},[190,1887,1888],{"class":196},"      draft: ",[190,1890,807],{"class":778},[190,1892,729],{"class":196},[190,1894,1895],{"class":192,"line":925},[190,1896,1035],{"class":196},[190,1898,1899,1901,1903,1905,1907,1909],{"class":192,"line":937},[190,1900,1692],{"class":676},[190,1902,1695],{"class":778},[190,1904,1352],{"class":676},[190,1906,1700],{"class":196},[190,1908,1703],{"class":219},[190,1910,1911],{"class":196},"(context);\n",[190,1913,1914],{"class":192,"line":942},[190,1915,379],{"emptyLinePlaceholder":378},[190,1917,1918,1920,1922,1924,1926,1928,1930,1932],{"class":192,"line":948},[190,1919,1717],{"class":219},[190,1921,1055],{"class":196},[190,1923,1722],{"class":219},[190,1925,1725],{"class":196},[190,1927,1728],{"class":219},[190,1929,1055],{"class":196},[190,1931,1583],{"class":226},[190,1933,1934],{"class":196},");\n",[190,1936,1937],{"class":192,"line":953},[190,1938,1736],{"class":196},[190,1940,1941],{"class":192,"line":962},[190,1942,1943],{"class":196},"});\n",[13,1945,1946,1947,176],{},"Along with an explanation of ",[100,1948,1296],{},[164,1950,1951],{},[13,1952,1953,1954,1956],{},"Note that ",[100,1955,1296],{}," is a utility provided by Jest that allows you to write the same test with different inputs and expected results. This can make your tests more concise and easier to read.",[13,1958,1959],{},"Our next steps were to:",[36,1961,1962,1965,1968,1971],{},[39,1963,1964],{},"Paste the output from ChatGPT into the Web IDE.",[39,1966,1967],{},"Click the blue “Commit” button to commit the code.",[39,1969,1970],{},"Name the branch.",[39,1972,1973],{},"Open a merge request.",[13,1975,1976,1977,1982],{},"All of this can be done inside ",[17,1978,1981],{"href":1979,"rel":1980},"https://docs.gitlab.com/user/project/web_ide/",[],"GitLab’s Web IDE"," without leaving the browser.",[134,1984,1986],{"id":1985},"examining-the-results","Examining the results",[13,1988,1989,1990,1992],{},"Once we opened the merge request, a CI/CD pipeline was created to test the change. Unfortunately, the pipeline jobs for the Jest tests failed because the tests were returning ",[100,1991,1481],{}," for each case instead of the expected results. We went back to ChatGPT to see if it could help us understand why the test was returning null for all cases. ChatGPT suggested a few different implementations to check to make sure things are defined currently:",[164,1994,1995,2001],{},[13,1996,1997,1998,2000],{},"There are a few reasons why the tests in the ",[100,1999,1296],{}," function might be returning null for every case. Here are a few possibilities:",[13,2002,2003,2004,2007,2008,2010,2011,2013],{},"If the ",[100,2005,2006],{},"getStateKey"," function is not implemented correctly, it might always return null, regardless of the input.\nIf the ",[100,2009,2006],{}," function relies on certain variables that are not defined in the test cases, it might return null because those variables are undefined.\nIf the context object passed to the ",[100,2012,2006],{}," function is not being merged correctly with the input object in the test cases, the function might not have access to all of the necessary information, and it might return null.",[13,2015,2016,2017,2022,2023,2025,2026,2028],{},"While ChatGPT couldn’t solve the issue with the returned value directly, it provided a lot of possibilities to look into and offered suggestions of what variables or functions to debug. The suggestions prompted us to add code changes that logged the variable values onto the ",[17,2018,2021],{"href":2019,"rel":2020},"https://www.w3schools.com/js/js_debugging.asp",[],"JavaScript debug console",", find the implementation of the ",[100,2024,2006],{}," function, and figure out why the return value was null. Whenever we came across something unfamiliar in the code, like syntax in the ",[100,2027,1296],{}," that wasn’t familiar, we asked ChatGPT for clarification or a helpful example. Many times throughout this experiment, working with ChatGPT felt like “rubber duck debugging,” but with an AI with which you have to be very specific about your ask.",[73,2030,2032],{"id":2031},"what-we-learned-from-chatgpt","What we learned from ChatGPT",[13,2034,2035,2036,2041],{},"In the end, we weren’t able to figure out why our tests were returning null, so we asked the front-end team if someone could review the code. Senior Frontend Engineer ",[17,2037,2040],{"href":2038,"rel":2039},"https://gitlab.com/agulina",[],"Angelo Gulina"," reviewed the MR. He found that the solution was actually quite trivial: The order of parameters was inverted, resulting in a comparison that led to null! In his assessment, ChatGPT wasn’t able to provide a working solution, but would be able to provide solutions and ideas to an engineer with some experience with the codebase. It delivered a clean, organized solution and answered the task of combining the tests into an it.each table. It could not, however, catch the actual error (the inversion of parameters) or correctly guess why the tests were returning null.",[13,2043,2044],{},"Let's circle back to the question that started this experiment: Can we use ChatGPT to contribute to GitLab? At this time, we’d say, \"yes,\" and you will need some understanding of the code to complete your solution. Since ChatGPT is a language model trained by OpenAI, it can only answer questions and provide information addressed in the model, which means answers requiring contextual specificity may fall short of what is needed to resolve an issue. However, it’s a tool that can help you if you’re stuck, need more clarification on a code snippet, or are trying to refactor some code. It was fascinating for us to experiment with ChatGPT and we were excited to see what it was capable of. The code provided, however, lacked some of the valuable insight and industry experience that a community of contributors can provide.",[13,2046,2047],{},"At GitLab, our community and our open source stewardship are part of our company strategy. Thousands of open source contributors worldwide have helped make GitLab what it is today. We see potential for ChatGPT and similar AI tools, not as a replacement for our community, but a way to make our community more efficient and enable more people to contribute GitLab.",[2049,2050,2051],"style",{},"html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sB1qb, html code.shiki .sB1qb{--shiki-default:#B31D28;--shiki-default-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}",{"title":186,"searchDepth":207,"depth":207,"links":2053},[2054,2059],{"id":75,"depth":207,"text":76,"children":2055},[2056,2057,2058],{"id":136,"depth":216,"text":137},{"id":1261,"depth":216,"text":1262},{"id":1985,"depth":216,"text":1986},{"id":2031,"depth":207,"text":2032},"engineering","2022-12-15","We put ChatGPT to the test to see if it could contribute to GitLab. Here's what we learned.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749670171/Blog/Hero%20Images/akshay-nanavati-Zq6HerrBPEs-unsplash.jpg",{},"/en-us/blog/can-chatgpt-resolve-gitlab-issues",{"title":5,"description":2062,"ogTitle":5,"ogDescription":2062,"noIndex":2065,"ogImage":2066,"ogUrl":2070,"ogSiteName":2071,"ogType":2072,"canonicalUrls":2070},"https://about.gitlab.com/blog/can-chatgpt-resolve-gitlab-issues","https://about.gitlab.com","article","can-chatgpt-resolve-gitlab-issues","en-us/blog/can-chatgpt-resolve-gitlab-issues",[2076,2077,2078,2079],"tutorial","community","contributors","DevOps","BlogPost","k5rT699zKT4S0B2J2WYJqiEpjyMXNzemiggFLZllgbA",{"logo":2083,"freeTrial":2088,"sales":2093,"login":2098,"items":2103,"search":2428,"minimal":2459,"duo":2478,"switchNav":2487,"pricingDeployment":2498},{"config":2084},{"href":2085,"dataGaName":2086,"dataGaLocation":2087},"/","gitlab logo","header",{"text":2089,"config":2090},"Get free trial",{"href":2091,"dataGaName":2092,"dataGaLocation":2087},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":2094,"config":2095},"Request a demo",{"href":2096,"dataGaName":2097,"dataGaLocation":2087},"/sales/?contact-topic=request-demo","sales",{"text":2099,"config":2100},"Sign in",{"href":2101,"dataGaName":2102,"dataGaLocation":2087},"https://gitlab.com/users/sign_in/","sign in",[2104,2133,2233,2238,2350,2406],{"text":2105,"config":2106,"menu":2108},"Platform",{"dataNavLevelOne":2107},"platform",{"type":2109,"columns":2110},"cards",[2111,2117,2125],{"title":2105,"description":2112,"link":2113},"The intelligent orchestration platform for DevSecOps",{"text":2114,"config":2115},"Explore our Platform",{"href":2116,"dataGaName":2107,"dataGaLocation":2087},"/platform/",{"title":2118,"description":2119,"link":2120},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":2121,"config":2122},"Meet GitLab Duo",{"href":2123,"dataGaName":2124,"dataGaLocation":2087},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":2126,"description":2127,"link":2128},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":2129,"config":2130},"Learn more",{"href":2131,"dataGaName":2132,"dataGaLocation":2087},"/why-gitlab/","why gitlab",{"text":2134,"left":378,"config":2135,"menu":2137},"Product",{"dataNavLevelOne":2136},"solutions",{"type":2138,"link":2139,"columns":2143,"feature":2212},"lists",{"text":2140,"config":2141},"View all Solutions",{"href":2142,"dataGaName":2136,"dataGaLocation":2087},"/solutions/",[2144,2168,2191],{"title":2145,"description":2146,"link":2147,"items":2152},"Automation","CI/CD and automation to accelerate deployment",{"config":2148},{"icon":2149,"href":2150,"dataGaName":2151,"dataGaLocation":2087},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[2153,2157,2160,2164],{"text":2154,"config":2155},"CI/CD",{"href":2156,"dataGaLocation":2087,"dataGaName":2154},"/solutions/continuous-integration/",{"text":2118,"config":2158},{"href":2123,"dataGaLocation":2087,"dataGaName":2159},"gitlab duo agent platform - product menu",{"text":2161,"config":2162},"Source Code Management",{"href":2163,"dataGaLocation":2087,"dataGaName":2161},"/solutions/source-code-management/",{"text":2165,"config":2166},"Automated Software Delivery",{"href":2150,"dataGaLocation":2087,"dataGaName":2167},"Automated software delivery",{"title":2169,"description":2170,"link":2171,"items":2176},"Security","Deliver code faster without compromising security",{"config":2172},{"href":2173,"dataGaName":2174,"dataGaLocation":2087,"icon":2175},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[2177,2181,2186],{"text":2178,"config":2179},"Application Security Testing",{"href":2173,"dataGaName":2180,"dataGaLocation":2087},"Application security testing",{"text":2182,"config":2183},"Software Supply Chain Security",{"href":2184,"dataGaLocation":2087,"dataGaName":2185},"/solutions/supply-chain/","Software supply chain security",{"text":2187,"config":2188},"Software Compliance",{"href":2189,"dataGaName":2190,"dataGaLocation":2087},"/solutions/software-compliance/","software compliance",{"title":2192,"link":2193,"items":2198},"Measurement",{"config":2194},{"icon":2195,"href":2196,"dataGaName":2197,"dataGaLocation":2087},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[2199,2203,2207],{"text":2200,"config":2201},"Visibility & Measurement",{"href":2196,"dataGaLocation":2087,"dataGaName":2202},"Visibility and Measurement",{"text":2204,"config":2205},"Value Stream Management",{"href":2206,"dataGaLocation":2087,"dataGaName":2204},"/solutions/value-stream-management/",{"text":2208,"config":2209},"Analytics & Insights",{"href":2210,"dataGaLocation":2087,"dataGaName":2211},"/solutions/analytics-and-insights/","Analytics and insights",{"title":2213,"type":2138,"items":2214},"GitLab for",[2215,2221,2227],{"text":2216,"config":2217},"Enterprise",{"icon":2218,"href":2219,"dataGaLocation":2087,"dataGaName":2220},"Building","/enterprise/","enterprise",{"text":2222,"config":2223},"Small Business",{"icon":2224,"href":2225,"dataGaLocation":2087,"dataGaName":2226},"Work","/small-business/","small business",{"text":2228,"config":2229},"Public Sector",{"icon":2230,"href":2231,"dataGaLocation":2087,"dataGaName":2232},"Organization","/solutions/public-sector/","public sector",{"text":2234,"config":2235},"Pricing",{"href":2236,"dataGaName":2237,"dataGaLocation":2087,"dataNavLevelOne":2237},"/pricing/","pricing",{"text":2239,"config":2240,"menu":2242},"Resources",{"dataNavLevelOne":2241},"resources",{"type":2138,"link":2243,"columns":2247,"feature":2339},{"text":2244,"config":2245},"View all resources",{"href":2246,"dataGaName":2241,"dataGaLocation":2087},"/resources/",[2248,2280,2307],{"title":137,"items":2249},[2250,2255,2260,2265,2270,2275],{"text":2251,"config":2252},"Install",{"href":2253,"dataGaName":2254,"dataGaLocation":2087},"/install/","install",{"text":2256,"config":2257},"Quick start guides",{"href":2258,"dataGaName":2259,"dataGaLocation":2087},"/get-started/","quick setup checklists",{"text":2261,"config":2262},"Learn",{"href":2263,"dataGaLocation":2087,"dataGaName":2264},"https://university.gitlab.com/","learn",{"text":2266,"config":2267},"Product documentation",{"href":2268,"dataGaName":2269,"dataGaLocation":2087},"https://docs.gitlab.com/","product documentation",{"text":2271,"config":2272},"Best practice videos",{"href":2273,"dataGaName":2274,"dataGaLocation":2087},"/getting-started-videos/","best practice videos",{"text":2276,"config":2277},"Integrations",{"href":2278,"dataGaName":2279,"dataGaLocation":2087},"/integrations/","integrations",{"title":2281,"items":2282},"Discover",[2283,2288,2293,2298,2302],{"text":2284,"config":2285},"Customer success stories",{"href":2286,"dataGaName":2287,"dataGaLocation":2087},"/customers/","customer success stories",{"text":2289,"config":2290},"Blog",{"href":2291,"dataGaName":2292,"dataGaLocation":2087},"/blog/","blog",{"text":2294,"config":2295},"Demo Hub",{"href":2296,"dataGaName":2297,"dataGaLocation":2087},"/demo-hub/","demo hub",{"text":2299,"config":2300},"The Source",{"href":2301,"dataGaName":2292,"dataGaLocation":2087},"/the-source/",{"text":2303,"config":2304},"Remote",{"href":2305,"dataGaName":2306,"dataGaLocation":2087},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":2308,"items":2309},"Connect",[2310,2315,2320,2324,2329,2334],{"text":2311,"config":2312},"GitLab Services",{"href":2313,"dataGaName":2314,"dataGaLocation":2087},"/services/","services",{"text":2316,"config":2317},"Contribute",{"href":2318,"dataGaName":2319,"dataGaLocation":2087},"https://contributors.gitlab.com","contribute",{"text":2321,"config":2322},"Community",{"href":2323,"dataGaName":2077,"dataGaLocation":2087},"/community/",{"text":2325,"config":2326},"Forum",{"href":2327,"dataGaName":2328,"dataGaLocation":2087},"https://forum.gitlab.com/","forum",{"text":2330,"config":2331},"Events",{"href":2332,"dataGaName":2333,"dataGaLocation":2087},"/events/","events",{"text":2335,"config":2336},"Partners",{"href":2337,"dataGaName":2338,"dataGaLocation":2087},"/partners/","partners",{"config":2340,"title":2343,"text":2344,"link":2345},{"background":2341,"textColor":2342},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":2346,"config":2347},"Read the latest",{"href":2348,"dataGaName":2349,"dataGaLocation":2087},"/whats-new/","whats new",{"text":2351,"config":2352,"menu":2354},"Company",{"dataNavLevelOne":2353},"company",{"type":2138,"columns":2355},[2356],{"items":2357},[2358,2363,2369,2371,2376,2381,2386,2391,2396,2401],{"text":2359,"config":2360},"About",{"href":2361,"dataGaName":2362,"dataGaLocation":2087},"/company/","about",{"text":2364,"config":2365,"footerGa":2368},"Jobs",{"href":2366,"dataGaName":2367,"dataGaLocation":2087},"/jobs/","jobs",{"dataGaName":2367},{"text":2330,"config":2370},{"href":2332,"dataGaName":2333,"dataGaLocation":2087},{"text":2372,"config":2373},"Leadership",{"href":2374,"dataGaName":2375,"dataGaLocation":2087},"/company/team/e-group/","leadership",{"text":2377,"config":2378},"Handbook",{"href":2379,"dataGaName":2380,"dataGaLocation":2087},"https://handbook.gitlab.com/","handbook",{"text":2382,"config":2383},"Investor relations",{"href":2384,"dataGaName":2385,"dataGaLocation":2087},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":2387,"config":2388},"Trust Center",{"href":2389,"dataGaName":2390,"dataGaLocation":2087},"/security/","trust center",{"text":2392,"config":2393},"AI Transparency Center",{"href":2394,"dataGaName":2395,"dataGaLocation":2087},"/ai-transparency-center/","ai transparency center",{"text":2397,"config":2398},"Newsletter",{"href":2399,"dataGaName":2400,"dataGaLocation":2087},"/company/contact/#contact-forms","newsletter",{"text":2402,"config":2403},"Press",{"href":2404,"dataGaName":2405,"dataGaLocation":2087},"/press/","press",{"text":2407,"config":2408,"menu":2409},"Contact us",{"dataNavLevelOne":2353},{"type":2138,"columns":2410},[2411],{"items":2412},[2413,2418,2423],{"text":2414,"config":2415},"Talk to sales",{"href":2416,"dataGaName":2417,"dataGaLocation":2087},"/sales/","talk to sales",{"text":2419,"config":2420},"Support portal",{"href":2421,"dataGaName":2422,"dataGaLocation":2087},"https://support.gitlab.com/hc/en-us","support portal",{"text":2424,"config":2425},"Customer portal",{"href":2426,"dataGaName":2427,"dataGaLocation":2087},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":2429,"login":2430,"suggestions":2437},"Close",{"text":2431,"link":2432},"To search repositories and projects, login to",{"text":2433,"config":2434},"gitlab.com",{"href":2101,"dataGaName":2435,"dataGaLocation":2436},"search login","search",{"text":2438,"default":2439},"Suggestions",[2440,2442,2446,2448,2452,2456],{"text":2118,"config":2441},{"href":2123,"dataGaName":2118,"dataGaLocation":2436},{"text":2443,"config":2444},"Code Suggestions (AI)",{"href":2445,"dataGaName":2443,"dataGaLocation":2436},"/solutions/code-suggestions/",{"text":2154,"config":2447},{"href":2156,"dataGaName":2154,"dataGaLocation":2436},{"text":2449,"config":2450},"GitLab on AWS",{"href":2451,"dataGaName":2449,"dataGaLocation":2436},"/partners/technology-partners/aws/",{"text":2453,"config":2454},"GitLab on Google Cloud",{"href":2455,"dataGaName":2453,"dataGaLocation":2436},"/partners/technology-partners/google-cloud-platform/",{"text":2457,"config":2458},"Why GitLab?",{"href":2131,"dataGaName":2457,"dataGaLocation":2436},{"freeTrial":2460,"mobileIcon":2465,"desktopIcon":2470,"secondaryButton":2473},{"text":2461,"config":2462},"Start free trial",{"href":2463,"dataGaName":2092,"dataGaLocation":2464},"https://gitlab.com/-/trials/new/","nav",{"altText":2466,"config":2467},"Gitlab Icon",{"src":2468,"dataGaName":2469,"dataGaLocation":2464},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":2466,"config":2471},{"src":2472,"dataGaName":2469,"dataGaLocation":2464},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":2474,"config":2475},"Get Started",{"href":2476,"dataGaName":2477,"dataGaLocation":2464},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":2479,"mobileIcon":2483,"desktopIcon":2485},{"text":2480,"config":2481},"Learn more about GitLab Duo",{"href":2123,"dataGaName":2482,"dataGaLocation":2464},"gitlab duo",{"altText":2466,"config":2484},{"src":2468,"dataGaName":2469,"dataGaLocation":2464},{"altText":2466,"config":2486},{"src":2472,"dataGaName":2469,"dataGaLocation":2464},{"button":2488,"mobileIcon":2493,"desktopIcon":2495},{"text":2489,"config":2490},"/switch",{"href":2491,"dataGaName":2492,"dataGaLocation":2464},"#contact","switch",{"altText":2466,"config":2494},{"src":2468,"dataGaName":2469,"dataGaLocation":2464},{"altText":2466,"config":2496},{"src":2497,"dataGaName":2469,"dataGaLocation":2464},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":2499,"mobileIcon":2504,"desktopIcon":2506},{"text":2500,"config":2501},"Back to pricing",{"href":2236,"dataGaName":2502,"dataGaLocation":2464,"icon":2503},"back to pricing","GoBack",{"altText":2466,"config":2505},{"src":2468,"dataGaName":2469,"dataGaLocation":2464},{"altText":2466,"config":2507},{"src":2472,"dataGaName":2469,"dataGaLocation":2464},{"title":2509,"titleMobile":2510,"button":2511,"config":2516},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":2129,"config":2512},{"href":2513,"dataGaName":2514,"dataGaLocation":2515},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":2517,"disabled":2065},"release",{"data":2519},{"text":2520,"source":2521,"edit":2527,"contribute":2532,"config":2537,"items":2542,"minimal":2751},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":2522,"config":2523},"View page source",{"href":2524,"dataGaName":2525,"dataGaLocation":2526},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":2528,"config":2529},"Edit this page",{"href":2530,"dataGaName":2531,"dataGaLocation":2526},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":2533,"config":2534},"Please contribute",{"href":2535,"dataGaName":2536,"dataGaLocation":2526},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":2538,"facebook":2539,"youtube":2540,"linkedin":2541},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[2543,2590,2643,2687,2719],{"title":2234,"links":2544,"subMenu":2559},[2545,2549,2554],{"text":2546,"config":2547},"View plans",{"href":2236,"dataGaName":2548,"dataGaLocation":2526},"view plans",{"text":2550,"config":2551},"Why Premium?",{"href":2552,"dataGaName":2553,"dataGaLocation":2526},"/pricing/premium/","why premium",{"text":2555,"config":2556},"Why Ultimate?",{"href":2557,"dataGaName":2558,"dataGaLocation":2526},"/pricing/ultimate/","why ultimate",[2560],{"title":2561,"links":2562},"Contact Us",[2563,2566,2568,2570,2575,2580,2585],{"text":2564,"config":2565},"Contact sales",{"href":2416,"dataGaName":2097,"dataGaLocation":2526},{"text":2419,"config":2567},{"href":2421,"dataGaName":2422,"dataGaLocation":2526},{"text":2424,"config":2569},{"href":2426,"dataGaName":2427,"dataGaLocation":2526},{"text":2571,"config":2572},"Status",{"href":2573,"dataGaName":2574,"dataGaLocation":2526},"https://status.gitlab.com/","status",{"text":2576,"config":2577},"Terms of use",{"href":2578,"dataGaName":2579,"dataGaLocation":2526},"/terms/","terms of use",{"text":2581,"config":2582},"Privacy statement",{"href":2583,"dataGaName":2584,"dataGaLocation":2526},"/privacy/","privacy statement",{"text":2586,"config":2587},"Cookie preferences",{"dataGaName":2588,"dataGaLocation":2526,"id":2589,"isOneTrustButton":378},"cookie preferences","ot-sdk-btn",{"title":2134,"links":2591,"subMenu":2600},[2592,2596],{"text":2593,"config":2594},"DevSecOps platform",{"href":2116,"dataGaName":2595,"dataGaLocation":2526},"devsecops platform",{"text":2597,"config":2598},"AI-Assisted Development",{"href":2123,"dataGaName":2599,"dataGaLocation":2526},"ai-assisted development",[2601],{"title":2602,"links":2603},"Topics",[2604,2609,2614,2618,2623,2628,2633,2638],{"text":2605,"config":2606},"CICD",{"href":2607,"dataGaName":2608,"dataGaLocation":2526},"/topics/ci-cd/","cicd",{"text":2610,"config":2611},"GitOps",{"href":2612,"dataGaName":2613,"dataGaLocation":2526},"/topics/gitops/","gitops",{"text":2079,"config":2615},{"href":2616,"dataGaName":2617,"dataGaLocation":2526},"/topics/devops/","devops",{"text":2619,"config":2620},"Version Control",{"href":2621,"dataGaName":2622,"dataGaLocation":2526},"/topics/version-control/","version control",{"text":2624,"config":2625},"DevSecOps",{"href":2626,"dataGaName":2627,"dataGaLocation":2526},"/topics/devsecops/","devsecops",{"text":2629,"config":2630},"Cloud Native",{"href":2631,"dataGaName":2632,"dataGaLocation":2526},"/topics/cloud-native/","cloud native",{"text":2634,"config":2635},"AI for Coding",{"href":2636,"dataGaName":2637,"dataGaLocation":2526},"/topics/devops/ai-for-coding/","ai for coding",{"text":2639,"config":2640},"Agentic AI",{"href":2641,"dataGaName":2642,"dataGaLocation":2526},"/topics/agentic-ai/","agentic ai",{"title":2644,"links":2645},"Solutions",[2646,2648,2650,2655,2659,2662,2666,2669,2671,2674,2677,2682],{"text":2178,"config":2647},{"href":2173,"dataGaName":2178,"dataGaLocation":2526},{"text":2167,"config":2649},{"href":2150,"dataGaName":2151,"dataGaLocation":2526},{"text":2651,"config":2652},"Agile development",{"href":2653,"dataGaName":2654,"dataGaLocation":2526},"/solutions/agile-delivery/","agile delivery",{"text":2656,"config":2657},"SCM",{"href":2163,"dataGaName":2658,"dataGaLocation":2526},"source code management",{"text":2605,"config":2660},{"href":2156,"dataGaName":2661,"dataGaLocation":2526},"continuous integration & delivery",{"text":2663,"config":2664},"Value stream management",{"href":2206,"dataGaName":2665,"dataGaLocation":2526},"value stream management",{"text":2610,"config":2667},{"href":2668,"dataGaName":2613,"dataGaLocation":2526},"/solutions/gitops/",{"text":2216,"config":2670},{"href":2219,"dataGaName":2220,"dataGaLocation":2526},{"text":2672,"config":2673},"Small business",{"href":2225,"dataGaName":2226,"dataGaLocation":2526},{"text":2675,"config":2676},"Public sector",{"href":2231,"dataGaName":2232,"dataGaLocation":2526},{"text":2678,"config":2679},"Education",{"href":2680,"dataGaName":2681,"dataGaLocation":2526},"/solutions/education/","education",{"text":2683,"config":2684},"Financial services",{"href":2685,"dataGaName":2686,"dataGaLocation":2526},"/solutions/finance/","financial services",{"title":2239,"links":2688},[2689,2691,2693,2695,2698,2700,2703,2705,2707,2709,2711,2713,2715,2717],{"text":2251,"config":2690},{"href":2253,"dataGaName":2254,"dataGaLocation":2526},{"text":2256,"config":2692},{"href":2258,"dataGaName":2259,"dataGaLocation":2526},{"text":2261,"config":2694},{"href":2263,"dataGaName":2264,"dataGaLocation":2526},{"text":2266,"config":2696},{"href":2268,"dataGaName":2697,"dataGaLocation":2526},"docs",{"text":2289,"config":2699},{"href":2291,"dataGaName":2292,"dataGaLocation":2526},{"text":2701,"config":2702},"What's new",{"href":2348,"dataGaName":2349,"dataGaLocation":2526},{"text":2284,"config":2704},{"href":2286,"dataGaName":2287,"dataGaLocation":2526},{"text":2303,"config":2706},{"href":2305,"dataGaName":2306,"dataGaLocation":2526},{"text":2311,"config":2708},{"href":2313,"dataGaName":2314,"dataGaLocation":2526},{"text":2316,"config":2710},{"href":2318,"dataGaName":2319,"dataGaLocation":2526},{"text":2321,"config":2712},{"href":2323,"dataGaName":2077,"dataGaLocation":2526},{"text":2325,"config":2714},{"href":2327,"dataGaName":2328,"dataGaLocation":2526},{"text":2330,"config":2716},{"href":2332,"dataGaName":2333,"dataGaLocation":2526},{"text":2335,"config":2718},{"href":2337,"dataGaName":2338,"dataGaLocation":2526},{"title":2351,"links":2720},[2721,2723,2725,2727,2729,2731,2735,2740,2742,2744,2746],{"text":2359,"config":2722},{"href":2361,"dataGaName":2353,"dataGaLocation":2526},{"text":2364,"config":2724},{"href":2366,"dataGaName":2367,"dataGaLocation":2526},{"text":2372,"config":2726},{"href":2374,"dataGaName":2375,"dataGaLocation":2526},{"text":2377,"config":2728},{"href":2379,"dataGaName":2380,"dataGaLocation":2526},{"text":2382,"config":2730},{"href":2384,"dataGaName":2385,"dataGaLocation":2526},{"text":2732,"config":2733},"Sustainability",{"href":2734,"dataGaName":2732,"dataGaLocation":2526},"/sustainability/",{"text":2736,"config":2737},"Diversity, inclusion and belonging (DIB)",{"href":2738,"dataGaName":2739,"dataGaLocation":2526},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":2387,"config":2741},{"href":2389,"dataGaName":2390,"dataGaLocation":2526},{"text":2397,"config":2743},{"href":2399,"dataGaName":2400,"dataGaLocation":2526},{"text":2402,"config":2745},{"href":2404,"dataGaName":2405,"dataGaLocation":2526},{"text":2747,"config":2748},"Modern Slavery Transparency Statement",{"href":2749,"dataGaName":2750,"dataGaLocation":2526},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":2752},[2753,2756,2759],{"text":2754,"config":2755},"Terms",{"href":2578,"dataGaName":2579,"dataGaLocation":2526},{"text":2757,"config":2758},"Cookies",{"dataGaName":2588,"dataGaLocation":2526,"id":2589,"isOneTrustButton":378},{"text":2760,"config":2761},"Privacy",{"href":2583,"dataGaName":2584,"dataGaLocation":2526},[2763,2777],{"id":2764,"title":7,"body":2064,"config":2765,"content":2767,"description":2064,"extension":2771,"meta":2772,"navigation":378,"path":2773,"seo":2774,"stem":2775,"__hash__":2776},"blogAuthors/en-us/blog/authors/john-coghlan.yml",{"template":2766},"BlogAuthor",{"name":7,"config":2768},{"headshot":2769,"ctfId":2770},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749670167/Blog/Author%20Headshots/johncoghlan-headshot.jpg","johncoghlan","yml",{},"/en-us/blog/authors/john-coghlan",{},"en-us/blog/authors/john-coghlan","dOj1PXtB8h9xxt68I3Ck9deyy57w1js7NkehLQ5E8Pc",{"id":2778,"title":8,"body":2064,"config":2779,"content":2780,"description":2064,"extension":2771,"meta":2784,"navigation":378,"path":2785,"seo":2786,"stem":2787,"__hash__":2788},"blogAuthors/en-us/blog/authors/fatima-sarah-khalid.yml",{"template":2766},{"name":8,"config":2781},{"headshot":2782,"ctfId":2783},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663337/Blog/Author%20Headshots/sugaroverflow-headshot.jpg","sugaroverflow",{},"/en-us/blog/authors/fatima-sarah-khalid",{},"en-us/blog/authors/fatima-sarah-khalid","GpfAGDKB-pWdwSjPp8CXd-29am9proj8tK7mm1IN_rs",[2790,2799,2807],{"title":2791,"description":2792,"heroImage":2793,"category":2060,"date":2794,"authors":2795,"slug":2798,"externalUrl":2064},"Confidential AI for GitLab Self-Hosted","Give developers AI coding agents in GitLab Duo without source code leaving a hardware-encrypted boundary — no GPUs needed.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png","2026-08-06",[2796,2797],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":2800,"description":2801,"heroImage":2802,"category":2060,"date":2803,"authors":2804,"slug":2806,"externalUrl":2064},"Green DevOps: Why carbon measurement belongs in your CI/CD pipeline","CI/CD pipelines have a hidden carbon cost. Here's why measuring it matters, and how you can get started with Eco CI and Carmen in GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-07-09",[2805],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":2808,"description":2809,"heroImage":2810,"category":2060,"date":2811,"authors":2812,"slug":2814,"externalUrl":2064},"How to build CI/CD observability at scale","This practical guide to GitLab pipeline analytics helps self-managed users gain operational insights using Prometheus and Grafana.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-04-28",[2813],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":2816},[2817,2831,2843,2855],{"id":2818,"categories":2819,"header":2821,"text":2822,"button":2823,"image":2828},"ai-modernization",[2820],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":2824,"config":2825},"Get your AI maturity score",{"href":2826,"dataGaName":2827,"dataGaLocation":2292},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":2829},{"src":2830},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":2832,"categories":2833,"header":2835,"text":2822,"button":2836,"image":2840},"devops-modernization",[2834,2627],"product","Are you just managing tools or shipping innovation?",{"text":2837,"config":2838},"Get your DevOps maturity score",{"href":2839,"dataGaName":2827,"dataGaLocation":2292},"/assessments/devops-modernization-assessment/",{"config":2841},{"src":2842},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":2844,"categories":2845,"header":2847,"text":2822,"button":2848,"image":2852},"security-modernization",[2846],"security","Are you trading speed for security?",{"text":2849,"config":2850},"Get your security maturity score",{"href":2851,"dataGaName":2827,"dataGaLocation":2292},"/assessments/security-modernization-assessment/",{"config":2853},{"src":2854},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":2856,"paths":2857,"header":2860,"text":2861,"button":2862,"image":2867},"github-azure-migration",[2858,2859],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":2863,"config":2864},"See how GitLab compares to GitHub",{"href":2865,"dataGaName":2866,"dataGaLocation":2292},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":2868},{"src":2842},{"header":2870,"blurb":2871,"button":2872,"secondaryButton":2877},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":2873,"config":2874},"Get your free trial",{"href":2875,"dataGaName":2092,"dataGaLocation":2876},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":2564,"config":2878},{"href":2416,"dataGaName":2097,"dataGaLocation":2876},1786803745589]