<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 模塊使用 GitLab subgroups 的問(wèn)題

          共 4990字,需瀏覽 10分鐘

           ·

          2024-07-03 17:41

          大家好,我是煎魚。

          最近幫忙小伙伴處理了一個(gè)小問(wèn)題,感覺(jué)五六年前就有人問(wèn)過(guò)我,當(dāng)年覺(jué)得沒(méi)啥大問(wèn)題記錄。沒(méi)想到。。。2024 年了,還是有同學(xué)表示他的姿勢(shì)搜不到相關(guān)的解決辦法。

          今天主打一個(gè)分享和記載,看看有沒(méi)有也踩過(guò)坑的朋友。(結(jié)果我發(fā)文前兩天就有社區(qū)的朋友問(wèn)到了我??)

          我感覺(jué) 2027 年這問(wèn)題都不會(huì)解決。

          功能介紹

          在 GitLab 中,提供了一種叫做子組(subgroups)的功能特性。

          它允許對(duì)項(xiàng)目倉(cāng)庫(kù)進(jìn)行進(jìn)一步的分組,而無(wú)需創(chuàng)建多個(gè)組織去實(shí)現(xiàn)不同內(nèi)容的存放。

          創(chuàng)建子組的截圖和地方:

          新建子組

          在項(xiàng)目列表下子組的展示:

          列表展示

          注:這個(gè)功能,我翻了下 GitHub 是沒(méi)有的。并且有人在 Community Discussions#4837 提出也想要,但官方?jīng)]有人回應(yīng)此項(xiàng)提議。

          問(wèn)題背景

          雖然這個(gè)功能有一定的特色。但是子組(subgroups)和 Go 模塊管理有一定的水土不服。我們直接使用 go get 命令試圖拉取子組時(shí),就會(huì)出現(xiàn)問(wèn)題。

          在最常用的 group/project 格式下,模擬 go get 命令直接拉取:

          curl -X GET "https://gitlab.xxx.com/libraries/example?go-get=1"
          <html><head><meta name="go-import" content="gitlab.xxx.com/libraries/example git https://gitlab.xxx.com/libraries/example.git" /></head></html>

          可以看到是正常返回:gitlab.xxx.com/libraries/example.git

          那如果是子組的模式呢?

          我們按照 group/subgroup/project 再獲取試試:

          curl -X GET "https://gitlab.xxx.com/libraries/subgroup1/example?go-get=1"
          <html><head><meta name="go-import" content="gitlab.xxx.com/libraries/subgroup1 git https://gitlab.xxx.com/libraries/subgroup1.git" /></head></html>

          可以看到返回的是:gitlab.xxx.com/libraries/subgroup1.git,這顯然不正確。我們要獲取的是 gitlab.xxx.com/libraries/subgroup1/example。獲取到的層級(jí)都錯(cuò)了!

          不支持的原因

          現(xiàn)階段來(lái)看,根本原因是 Go 的 go get 實(shí)現(xiàn)和 GitLab 的原因共同導(dǎo)致。互相不完全適配。Go 覺(jué)得 GitLab 這個(gè)太定制化,GitLab 覺(jué)得是 Go 實(shí)現(xiàn)不完整。

          Go 為了使用 SSH 身份驗(yàn)證,go get 需要知道項(xiàng)目位于什么地方,然后才能去獲取他。

          以下是梳理的流程和步驟:

          1、對(duì)于 group/subgroup/project 中的項(xiàng)目,go get 將發(fā)送以下請(qǐng)求:

          • GET https://gitlab.com/group/subgroup/project?go-get=1
          • GET https://gitlab.com/group/subgroup?go-get=1
          • GET https://gitlab.com/group?go-get=1

          2、這些請(qǐng)求未經(jīng)授權(quán),因此 GitLab 無(wú)法提供指向項(xiàng)目的正確鏈接 (也就是預(yù)期的結(jié)果:https://gitlab.com/group/subgroup/project.git)。

          3、相反,GitLab 會(huì)返回 https://gitlab.com/group/subgroup.git 作為響應(yīng)結(jié)果。(如此返回的目的是:防止未經(jīng)身份驗(yàn)證的用戶訪問(wèn),避免出現(xiàn)暴露項(xiàng)目存在的安全風(fēng)險(xiǎn))

          4、然后 Go 會(huì)嘗試使用 SSH 身份驗(yàn)證 ssh://gitlab.com/group/subgroup.git 來(lái) git clone 倉(cāng)庫(kù)。想也知道,拉取的結(jié)果失敗了,因?yàn)檫@個(gè)倉(cāng)庫(kù)并不存在。

          因此對(duì)于 GitLab 子組中的 Go 私有項(xiàng)目,用戶必須通過(guò) HTTPS 認(rèn)證,這樣 Go 的 go get 命令才能通過(guò) GitLab 的訪問(wèn)校驗(yàn),再拉取到正確的響應(yīng)結(jié)果。

          解決方案

          現(xiàn)階段的解決方案大致有兩種,都是一些繞過(guò)校驗(yàn)或邏輯的操作。

          使用 .netrc 鑒權(quán)

          GitLab 文檔 Authenticate Go requests to private projects[1] 和 Go 文檔 Passing credentials to private proxies[2],推薦的是通過(guò)定義 .netrc 文件來(lái)實(shí)現(xiàn)該鑒權(quán)訪問(wèn)。

          但有前置條件的要求:

          • GitLab 實(shí)例必須可通過(guò) HTTPS 訪問(wèn)。
          • 用到的賬號(hào)必須擁有 read_api 權(quán)限的個(gè)人訪問(wèn)令牌。

          根據(jù)你的 OS 環(huán)境不同,創(chuàng)建一個(gè) .netrc 文件,并填入相關(guān)信息:

          machine gitlab.example.com
          login <gitlab_user_name>
          password <personal_access_token>

          需要注意:在 Windows 上,Go 讀取 ~/_netrc 而不是 Linux 的 ~/.netrc 文件。

          或者可以直接在 GOPROXY URL 鑒權(quán)憑證:

          GOPROXY=https://jrgopher:[email protected]

          采用此方法時(shí)請(qǐng)務(wù)必小心:環(huán)境變量可能會(huì)出現(xiàn)在 shell 歷史記錄和日志中。(不推薦使用)

          但總的來(lái)說(shuō),netrc 這個(gè)方案,有部分社區(qū)反饋不是很認(rèn)可,因?yàn)橛邪踩[患,存在一定的風(fēng)險(xiǎn)。還要配這配那的。

          使用 replace .git 繞過(guò)邏輯

          有一種方法更簡(jiǎn)單的方法,可以跳過(guò) go get 請(qǐng)求并強(qiáng)制 Go 直接使用 Git 身份驗(yàn)證,但需要修改模塊名稱。

          直接修改 go.mod 文件,采用 replace 的方式給實(shí)際引用的模塊名的項(xiàng)目名增加 .git。當(dāng)然,如果你不想 replace,直接引用模塊后綴是 .git 也是可以的。 

          如下所示:

          require(
              gitlab.xxx.com/group/subgroup/project v1.7.0
          )

          replace(
              gitlab.xxx.com/group/subgroup/project => gitlab.xxx.com/group/subgroup/project.git v1.7.0
          )

          Go 模塊能用這個(gè)騷操作的原因是:如果模塊路徑的某個(gè)組件末尾有一個(gè) VCS 標(biāo)識(shí)符符(例如:.bzr.fossil.git.hg.svn)。go get 命令就會(huì)使用該路徑限定符之前的所有內(nèi)容作為倉(cāng)庫(kù) URL。

          例如,對(duì)于 example.com/foo.git/bar 模塊,go 命令會(huì)使用 git 下載 example.com/foo.git 的版本庫(kù),并在 bar 子目錄中找到該模塊。

          總結(jié)和吐槽

          比較可惜的是,這個(gè)問(wèn)題,至少 7 年前(2017 年)就有人提出了,可惜到現(xiàn)在 2024 年,都沒(méi)有解決。

          追根溯源上,Go 團(tuán)隊(duì)并不想完整實(shí)現(xiàn)一套完整的單獨(dú)的程序去支持這個(gè)。Go 團(tuán)隊(duì)負(fù)責(zé)人 rsc(Go 模塊他獨(dú)立開(kāi)發(fā)、應(yīng)用和推廣的)只想做一個(gè)符合標(biāo)準(zhǔn)的,因此 Go 最終支持了讀取 $HOME/.netrc。后續(xù)至此再無(wú)更多的動(dòng)作。社區(qū)反饋也不會(huì)說(shuō)特別激烈。

          而對(duì)于 GitLab 而已,他是乙方。客戶各種吐槽。因此他們最有動(dòng)力去推進(jìn)解決這個(gè)事情。

          近期由于 Go 團(tuán)隊(duì)多年對(duì)此的冷漠。GitLab 開(kāi)始也有提出 Allow to set a go-modules folder for private Go projects[3]

          希望允許用戶在 group 或者子組為私有 Go 模塊設(shè)置 go-modules 的專屬標(biāo)識(shí)再通過(guò)第二點(diǎn)解決方案的 .git 的方式繞過(guò)邏輯:

          預(yù)想的定制

          不過(guò)這個(gè)還在討論中,反對(duì)意見(jiàn)也不小。暫且茍住。

          大家在實(shí)際使用上,可以先看看 .netrcreplace .git 的方式。可能前者更標(biāo)準(zhǔn),后者更易用。這樣團(tuán)隊(duì)成員就不用每次都配置一遍了。

          推薦閱讀

          參考資料
          [1]

          Authenticate Go requests to private projects: https://docs.gitlab.com/ee/user/project/use_project_as_go_package.html#authenticate-go-requests-to-private-projects

          [2]

          Passing credentials to private proxies: https://go.dev/ref/mod#private-module-proxy-auth

          [3]

          Allow to set a go-modules folder for private Go projects: https://gitlab.com/gitlab-org/gitlab/-/issues/437005


          關(guān)注和加煎魚微信,

          一手消息和知識(shí),拉你進(jìn)技術(shù)交流群??



          你好,我是煎魚,出版過(guò) Go 暢銷書《Go 語(yǔ)言編程之旅》,再到獲得 GOP(Go 領(lǐng)域最有觀點(diǎn)專家)榮譽(yù),點(diǎn)擊藍(lán)字查看我的出書之路

          日常分享高質(zhì)量文章,輸出 Go 面試、工作經(jīng)驗(yàn)、架構(gòu)設(shè)計(jì),加微信拉讀者交流群,和大家交流!


          原創(chuàng)不易 點(diǎn)贊支持

          瀏覽 27
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美三级片视频网站 | 一级黄色A片 | 久久成人精品电影 | 自拍偷拍网址 | 日本三级在线观看中文字串 |