GitLab Open API 代碼量統計,讓你的努力被老闆看到

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"前言"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"敦煌系統"},{"type":"text","text":" 是我們政採雲前端團隊自研的項目開發全流程管理系統,目標是將項目開發的各流程全部管理起來。從項目創建,代碼初始,到代碼的本地開發,提測交付,測後發佈,版本回滾,數據統計等。本文便是該系統中遠程項目創建及數據統計部分的實現原理。後續陸續會有敦煌系統其餘部分技術文章發佈。歡迎大家先關注微信公衆號 “政採雲前端團隊”,或者掘金上關注 “政採雲前端團隊”,以便第一時間獲取最新信息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"簡介"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文主要介紹如何通過 GitLab Open API 進行項目創建、初始化代碼及團隊代碼量統計。前端工程化建設過程中,需要通過 Node 服務端進行 Git 倉庫創建、項目初始化和代碼量統計。經過一段時間開發探索,初步實現了需求。這裏做個記錄總結。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"一、需求"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建倉庫並進行代碼初始化"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"目的"},{"type":"text","text":":統一項目新建入口、項目開發模板,項目開發流程。節省新成員上手成本。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"具體功能"},{"type":"text","text":":團隊成員可以通過輸入項目名、GitLab 組、項目模板等字段直接創建 GitLab 倉庫,並根據選擇的模板及名稱等信息在已創建的 GitLab 倉庫裏進行項目初始化。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"代碼量統計"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"目的"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"量化團隊代碼質量,統計團隊工作量,監測業務吞吐量變化等。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在團隊中推行 Commit 提交規範。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"具體功能"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"獲取團隊成員的 Git Commit 信息,並存入數據庫,以 Commit 信息數據爲基礎做數據統計分析。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"提交信息不以 fix、feat、style、refactor 等開頭的 Commit 可繪製餅圖進行統計對比。以此推動 Commit 提交規範的施行。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"單個 Commit 行數超出一定數量則在統計圖中做出提示。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"二、創建項目"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"看過 GitLab Open API 文檔的人很容易就能找到創建接口,不過在創建之外我們還需要導入項目模板,修改相應的項目名稱,描述,作者等信息。這涉及到多個接口的組合調用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1、API 前綴  "},{"type":"codeinline","content":[{"type":"text","text":"https:\/\/GitLabHost\/api\/v4"}]},{"type":"text","text":" ,所有 GitLab Open API 都以此爲前綴,舉個創建項目接口的例子:"},{"type":"codeinline","content":[{"type":"text","text":"https:\/\/GitLabHost\/api\/v4\/projects"}]},{"type":"text","text":" 。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2、每個請求都需要帶上創建者的 Private Token 作爲參數。且要求該創建者有對應的權限。我這裏使用了統一的用戶 Front 作爲創建人。這樣一來創建項目就不需要獲取每個用戶的 Private Token 了。這樣做還有個好處:統計代碼量時,這部分複製代碼的代碼量會被算在 Front 這個虛擬用戶上,減少統計誤差。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/70\/70f782401f77da11f4ae1d465cef7271.webp","alt":"Image","title":"img","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建項目"}]}]}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"POST \/projects (此處只列中關鍵參數,更多參數請查看 GitLab 文檔)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"參數:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"name: 項目名(不傳 path 參數的話必填)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"path: 項目路徑(不傳 name 參數的話必填)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"namespace_id: 創建項目所在 Git 組的 id"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"description: 項目描述"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"import_url: 初始化項目的代碼路徑,格式:https:\/\/user:[email protected]\/path.git"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過調用以上接口就可以在目標 Git 組中創建出一個帶有初始化模板的項目了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/2f\/2f5f1e5379c2db49fa8bf3e02f262b2f.webp","alt":"Image","title":"img","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建項目"},{"type":"text","marks":[{"type":"strong"}],"text":"需要注意的是:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Front 要擁有目標 Git 組的 Master 權限纔可以創建。這裏就要求提前把 Front 加入到目標組中並賦予 Master 權限。以 front-test 組爲例:"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/63\/6334af6a2ff23ba66d66c69d815294cc.webp","alt":"Image","title":"img","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當前用戶也需要做權限判斷,這裏需要開發者在創建之前調用 "},{"type":"codeinline","content":[{"type":"text","text":"GET \/groups\/:id\/members"}]},{"type":"text","text":" 接口獲取組別用戶並對比當前人是否有權限創建了。比如:"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/03\/03591d73a519f90629eab042d9d64752.webp","alt":"Image","title":"img","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"access_level"},{"type":"text","text":" 就是權限值,分別對應爲"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"10 => Guest 權限"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"20 => Reporter 權限"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"30 => Developer 權限"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"40 => Master 權限"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"50 => Owner 權限"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"初始化項目信息"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建完項目之後要初始化項目信息,細心的同學可以發現上面創建好的項目中的 README.md 裏面的 name ,desc 還沒有被替換掉,接下來我們就要替換包括 README.md 和 Package.json 兩個文件中的一些關鍵信息了。"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讀取對應的文件,這裏直接在瀏覽器中訪問對應文件然後把路徑中的 blob 改成 raw 就可以直接讀取到對應的文件信息了。"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"舉個例子:"},{"type":"codeinline","content":[{"type":"text","text":"https:\/\/GitLabHost\/f2e-cube\/template\/leo-middle-react-pc-project\/blob\/master\/README.md"}]},{"type":"text","text":" 這個鏈接可以直接訪問到項目文件頁面,但得到卻不是單純的文件信息。"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/35\/3543ceaa0e2e78786d046821a5296207.webp","alt":"Image","title":"img","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"把 blob 改成 raw 即直接訪問 "},{"type":"codeinline","content":[{"type":"text","text":"https:\/\/GitLabHost\/f2e-cube\/template\/leo-front-vue-pc-component\/raw\/master\/README.md"}]},{"type":"text","text":" 就可以直接獲取到文件內容了。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/ad\/ada52f3da83ac47b60e039d352cdb6f0.webp","alt":"Image","title":"img","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讀取到文件信息之後,使用 Node 模板引擎把對應的數據注入到獲取的文件信息中就可以了。這裏服務端使用的是 EggJs 框架。模板引擎選用 Ejs 。"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關鍵代碼:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"const result = await this.ctx.renderString(readMeStr, {   author: userInfo.userName,   name: gitProjectInfo.name,   description: project.desc,   ...others, });"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"將渲染完成的字符串提交到已經創建的項目中。使用到創建 Commit 接口。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"POST \/projects\/:id\/repository\/commits (此處只列中關鍵參數,更多參數請查看 GitLab 文檔)參數:id: 項目 id (剛剛創建好項目時有返回項目信息,裏面包含項目 id)branch: 分支(這裏一般是 Master )commit_message: commit 信息actions: [] 修改項   action: 變更類型 create, delete, move, update (這裏是 update)   file_path: 變更文件的路徑   content: 變更後的內容即上面代碼中的 result"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"至此"},{"type":"text","text":",項目創建並初始化完成!"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/a2\/a282a3098d23cd5cc39f03d65b6f4f7d.webp","alt":"Image","title":"img","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到 name 和 desc 已經被替換成相應的項目名及中文描述了。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"三、代碼量統計"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"代碼量統計,在百度,谷歌搜索一下能搜出來一大把,但是基本上都是代碼拉到本地後,執行命令獲取項目的代碼量或者項目代碼的貢獻者的代碼量。比較普遍的方案是給項目加 Git Hook 。在項目提交之前調用請求把當前提交的代碼量傳給後端進行儲存統計。這樣做的"},{"type":"text","marks":[{"type":"strong"}],"text":"弊端"},{"type":"text","text":"有"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要所有的項目都加上 Git Hook 。對於幾十上百個歷史項目的團隊而言是個不小問題。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"歷史數據統計不到。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"GitLab API 中有個實體叫做 Event ,用戶每個操作都會有對應的 Event 產生並儲存。我們這裏便是通過 Event 進行代碼量統計。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"基本信息"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"API 前綴  "},{"type":"codeinline","content":[{"type":"text","text":"https:\/\/GitLabHost\/api\/v4"}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"每個請求都需要帶上查詢用戶的 Private Token 作爲參數。且要求該查詢用戶有對應的權限。我這裏使用了統一的用戶 Front 做爲查詢用戶。所有被統計項目中都需要加入 Front ,並賦予 Developer 及以上權限。(可以直接通過組賦權)"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"獲取所有需要統計代碼量的用戶的用戶名"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先通過釘釘接口獲取團隊所有用戶的用戶名(團隊釘釘用戶名和 Git 用戶名相同)。這一步對於不是太大的團隊可以通過手動獲取。"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"獲取對應用戶的 Git Id (如果團隊人員少,可手動收集)"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過 "},{"type":"codeinline","content":[{"type":"text","text":"GET \/users?username=:username"}]},{"type":"text","text":" 接口獲取用戶對應的 Git User 的 Id 。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/72\/72303d34e922b7d5293b1f531bb6c60e.webp","alt":"Image","title":"img","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"查詢用戶的 Event"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"獲取到所有用戶 Id 之後就可以調用 "},{"type":"codeinline","content":[{"type":"text","text":"GET \/users\/:id\/events"}]},{"type":"text","text":" 這個接口查詢到當前用戶的所有 Event 。這裏會包括有 Push 的 Event 。Event 中會有對應 Commit 信息和項目信息。不過這裏的 Commit 信息不全,不包含添加多少行代碼,刪除多少行代碼,總共多少行代碼的信息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/bb\/bb4d547a62513ae35f52cc2baf235fbb.webp","alt":"Image","title":"img","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"獲取 Commit 的詳細信息"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過上一步獲取的 Commit 信息中的 Id 和項目 Id 再查詢 Commit 的詳細信息: "},{"type":"codeinline","content":[{"type":"text","text":"GET \/projects\/:id\/repository\/commits\/:sha"}]},{"type":"text","text":" 。這裏這裏就可以獲取到 Commit 的 Stats 信息了。裏面包含 additions, deletions, total 信息。"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/b7\/b79f547d044451300c29053f17d3ed37.webp","alt":"Image","title":"img","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"存數據庫並設定定時任務"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"將獲取到的數據存入數據庫就可以做代碼量統計了。然後設置定時任務,每週跑一次或兩次進行代碼量統計。"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要注意的有"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有些操作或導致 Commit 重複,所以對於同一個人的 Commit 需要做去重。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"GitLab Events 只會存近一年的數據。所以運行當天也只能統計近一年的代碼。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一定要按人進行 Push 時間劃分,這樣第一次運行之後,後面就可以只取上次取的最後一次 Push 的時間之後的 Commit 了。請求數可以減少很多。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"執行過代碼之後發現了一些問題,比如:團隊成員誤操作將 node_modules 文件夾上傳等。這造成了統計代碼行數過多,解決辦法是過濾掉大於 10000 行(這個可以自由指定)的 commit 。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"問題"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因爲接口限制,請求數太多了,所以第一次跑任務會有點慢,大概需要我們團隊 40 多人大概需要跑二、三十分鐘。"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"後續"}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最新版本的 GitLab Open API 使用了 GraphQL 技術。可以解決以上問題。"}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"後記"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其實最開始的文章,我們沒有表述清楚,是我們寫稿和審稿沒注意到“代碼量審覈”會對一些看官帶來困擾。大家所處公司不一樣,可能確實會有部分公司,會以代碼量的多少來簡單粗暴的計算員工的 KPI,這點我們同樣覺得是不妥的。文中提及的代碼及代碼量的目的,在於便於接入團隊的代碼合規檢測(如兼容性 api 檢測、lint 檢測)服務,也在於便於從數據維度進行量化,驗證架構的升級和基礎設施的完善,對同學工作量的降低,可以有數據指標進行說明。我們希望基於技術、架構的升級,基礎設施和工具鏈路的完善,幫我們做到接近 less code 的目標,幫我們的同學變得更“懶”,能騰出更多時間去去關注和研究對業務的未來、個人的未來更有價值的事。也希望你能一起加入,幫我們更快接近、達到這一目標。"}]},{"type":"horizontalrule"},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"頭圖:Unsplash"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作者:簡明"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文:https:\/\/mp.weixin.qq.com\/s\/oZrc0PqFTHBZejOUV1CCQg"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文:GitLab Open API 代碼量統計,讓你的努力被老闆看到"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"來源:政採雲前端團隊 - 微信公衆號 [ID:Zoo-Team]"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"轉載:著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章