本文主要是想給希望開始寫開源項目的同學們一些開源項目維護的實操建議,也算是給自己梳理一下做一個開源項目需要註意的事項。 ...
前言
各位好久不見,有些小伙伴可能知道大概1年多以前我開始維護log-record項目(Java業務操作日誌記錄框架)。這期間項目陸陸續續更新迭代、發佈新版本,一路走來也踩了不少坑。這篇文章主要是想給希望開始寫開源項目的同學們一些開源項目維護的實操建議,也算是給自己梳理一下做一個開源項目需要註意的事項。
此外,本文討論的個人開源項目僅限於代碼為主的項目。像一些新聞、教程、電子書、工具集錦類開源倉庫,不在本文的討論範圍內。
當然了,如果你已經是一個經驗豐富的開源項目maintainer,那麼請趕緊關掉這篇文章,並且聯繫我,讓我好好抱大腿 :)
確定項目的主題和方向
首先,我們要重點探討如何準備個人開源項目。一個最基礎的思考是,你的項目靈感從哪裡來?當你覺得有了好的想法後,又應該做哪些事前調研工作?
積累靈感
積累靈感是開始一個開源項目的第一步。
很多時候靈感源自於我們日常的學習和技術工作上的積累。例如,在工作中遇到的問題,想解決的BUG,或者對某項技術的深入研究,它們都可能給你靈感。
此外,每天多多閱讀技術文章、關註技術新聞以及瀏覽Github Trending都是獲取靈感的好辦法,多元化地獲取信息對於積累靈感很重要。
做好事前調研,非必要,不造新輪子
之前碩士期間寫論文經驗的告訴我,當你對一個研究方向沒有瞭解全面的時候,你的大多數想法是很幼稚的,有很大可能已經有前人替你踩過了坑,或者有了現成的框架和產品。
所以在確定你的項目主題之前,一定要充分的進行調研和搜索,保證你的項目在某個方面具有獨特性。在調研過程中,你最好要羅列出現有和你相似的產品為何不能滿足你的訴求,而你的項目又和他們有哪些差異化的特色。
當然,凡事都不要走兩個極端,當你發現你的想法真的非常獨特,沒有人做的時候,你要考慮下是否是因為成本過大,或者受眾過小的原因,才導致沒有現成的產品,那麼你來做第一個吃螃蟹的人,會面臨的工作量和難度,你自己是否心中有數。
如果在經過認真的調研後,你發現你的想法確實在網路上沒有很好的產品,那麼它可以作為一個好的發力點。
一步步維護好你的作品
OK,當你有了靈感,並且對於自己的這個想法十分有信心之後,讓我們來討論一下,當你準備正式開始一個項目時,你應該遵循的一些方法和我個人的經驗。
對於一個開源項目,華麗的外表並非貶義。你可能需要花大量的工作去做編碼以外的工作。此外,你還需要一些推廣你開源項目的手段,畢竟,如果一個項目一直不被人看見,你也會很快失去動力。但是,不要害怕,有一個好的、有效的靈感其實已經成功了一半,讓我們從拙劣的模仿開始,慢慢成為大師。
能者摹形,大師竊意。
先入為主,寫好README
很多時候我們點開開源項目主頁,首先就會大致瀏覽下項目的README,所以無論如何也要把第一印象做好。
網上有很多關於如何寫開源項目README的文章,這裡就不展開講了,推薦一篇寫的還不錯的外網翻譯:如何寫出優雅且有意義的 README
對於我來說,有個很喜歡做的事就是貼上很多小徽章,用戶會先入為主的覺得你的項目,有點“專業”。下麵用幾個倉庫的截圖舉例子。
我的log-record也像上面的知名倉庫一樣,依葫蘆畫瓢,貼上了幾個我認為重要的徽章(Badge)
對於不同類型,不同語言的開源項目,README的寫法也千變萬化,我也沒法給大家推導出一個萬能公式,但是我可以給大家介紹幾類典型的README:
- spring-boot: 經典Java框架,這種類似的開源項目由於其龐大的生態體系,其README主要是介紹其概念,隨後給用戶指引到各種外部文檔鏈接。同類型的還有:langchain,hutool等。
- transmittable-thread-local: 框架類項目的中文README寫法完全可以參考它,Java用戶熟悉的跨線程ThreadLocal傳遞框架,同類型的還有:我自己的log-record等
- uptime-kuma: 工具類項目,用於監控各類服務狀態,其README基本就遵循了上文章提到的如何寫好工具項目README的方法,有LIVEDEMO,有徽章,有編譯、安裝方式,並且提供了詳細文檔的跳轉。
- ChatGLM-6B:還有一些帶學術性質的項目,比如很多大模型項目,其README會包含一些論文引用以及論文數據的復現方式等,同類型的還有:llama3
請多多參考優秀項目的README,將應有的模塊儘量補全,之後慢慢迭代。
儘量清晰的項目結構
除了README,清晰的目錄結構也很能吸引用戶,以hutool和我的log-record為例,由於是Maven項目,可以儘量讓用戶能夠看出module區分。此外,會有一些額外的文件夾,例如:
- .github: Github Action相關
- .gitee:Gitee Action相關
- docs: 文檔集合
- bin: 可執行腳本
- LICENSE:開源證書
- 等等。
比如hutool項目:
log-record項目則是按照Maven模塊進行了簡單劃分:
良好的Git Commit
一個良好的commit記錄能夠讓使用者對項目更有信心,也更有說服力,證明其contributor都是(至少錶面上是)對代碼質量有追求的開發者。
我的Log-record,做的不好的是我中英文混雜。如果你的倉庫明確面向中文互聯網,你可以全部以中文來寫,但是如果想面對全球用戶,還是儘量採用全英文為上策。
相反,一個差的commit log讓人第一感覺就是不專業。這一點要吐槽下hutool
做好版本管理
如果你做的是Java項目,那麼最好項目能夠索引到公共Maven倉庫中,才能吸引更多用戶,畢竟用戶最需要的是方便地拉取你的包,而不是手動下載上傳到用戶的私有倉庫里。其實大部分個人的Maven項目都可以提交到公共Maven倉庫中,可以參考之前我的文章:如何提交自己的項目到Maven公共倉庫
以我的log-record項目為例,我會按照下麵的順序,進行版本迭代:
- 開發新版本代碼
- 發行SNAPSHOT版,上傳至公共Maven倉庫
- 打Tag,發行RELEASE版,上傳至公共Maven倉庫
發行RELEASE版後,你的倉庫主頁上會有最新的版本信息,方便用戶查看和使用。
https://central.sonatype.com/artifact/cn.monitor4all/log-record-starter
極為重要的測試工作
這一點希望大家尤其重視,開源項目,也要儘量對用戶負責,對項目的質量有追求,所以做好項目的單元測試和其他集成測試等工作,並且最好能夠將你的測試覆蓋率展示出來,也能夠增強使用者的信心。
這裡推薦一個網站codecov,它能夠通過多種方式幫你的倉庫維護一個測試覆蓋率數據,並且通過API讀取覆蓋率數據展示在各種地方,比如展示在README中。
https://app.codecov.io/gh/qqxx6661/log-record/commits
一份可信的更新日誌
大部分項目都需要有明確的Release Log/Update Log,用來向用戶展示倉庫的特性更新和問題修複,也能夠記錄一路以來項目的迭代更新曆程。
恰巧最近正在學習reactor,發現其子項目的一個非常標準的Release Log
https://github.com/reactor/BlockHound/releases
善用其他包裝
在Github上,還有一些包裝項目的好辦法,Github支持organizations,個人可以註冊一個虛擬的組織,用組織的名義建立開源項目,往往更有說服力。
https://github.com/settings/organizations
使用其免費版本即可,對於一個開源項目來說基本夠用。
Github的更新還是比較頻繁的,及時跟上Github新的功能和特性,也許會對你的項目有更多的幫助。
適當宣傳
當你的項目有了一個最基礎的雛形時,你可以慢慢開始你的宣傳工作。還是那句話,不要覺得宣傳有什麼可恥的,如果一個項目一直不被人看見,你也會很快失去動力。那麼你會更容易半途而廢。
對於個人小項目,有一些常規的推廣方式:
- 技術公眾號推廣:比如向一些有流量的大公眾號主做推薦,投放。
- 參與技術社區推廣:發佈文章&參與活動
- Github和Gitee活動推廣
開源是個苦力活
最後一個章節,我們聊聊,做一個開源項目,我們到底為了什麼?出名?純粹好玩?實現個人價值?體現開源精神?賺錢?還是...老實說,開源真的是個苦力活。
不要期待經濟回報,請用愛發電
如果你的開源項目已經在穩定維護,並且有一定的用戶正在使用,那麼恭喜你,項目走上了正軌。但是需要潑冷水的是,大部分就算是有名的開源項目,很多時候是沒法給你帶來等價的商業回報的,你很可能在很長一段時間里都在用愛發電。
它能給你的主要是成就感和一點小小的知名度,以及這些知名度背後可能帶來的一些附加價值(這就很難去描述了)。
如果你真的想要通過它得到一些金錢回報,那在你的項目小有名氣後,以下幾種方式可能會有效果:
- 提供有償技術支持。
- 打造商業版本,區別於社區開源版,商業版閉源並向用戶收費。
- 尋找一些推廣商,在你的項目代碼倉庫和文檔中植入其“廣告”。
- 其他野路子...
這些事情的背後都要大量的時間和精力去推動,如果你和我一樣是一個上班族,那麼大概率你沒法同時兼顧工作和維護一個持續保持活躍的大型項目。所以很大可能是,你的項目在很長時間內一直是一個小而美的項目。
伸手黨
當你的項目有了流量,被很多開發同學搜索到了,你會獲得很多流量附帶的東西。
伸手黨就是其中一個,具體來說就是有很多網友,會要求你添加很多他們能想到的功能或者他們覺得你項目應該提供的功能。
遇到這種情況,你需要用心判斷,他們所要求你添加的功能是否背離你本身項目的初衷,如果是,那麼請忽視這些建議。如果是合理的功能,那麼請考慮加入,但是可以和用戶說明,會在下一個裡程碑中加入,不要讓用戶過於期待你能很快完成。(如果用戶真的很希望能立馬用到此功能,你可以建議他自己開分支提交PR)。
無窮無盡的ISSUE
除了伸手黨之外,還會有很多用戶在ISSUE區問很多問題,例如我的log-record倉庫下這些例子。很多時候,用戶對你的項目不熟悉,自然會有一些提問,當遇到重覆的提問時,要有耐心,你可以儘量關聯到重覆問題的老ISSUE上,讓他們自己跳過去看。
此外,善用Github提供的各種標簽,歸類功能,把ISSUE分類,也是間接給用戶參與感,讓他們知道你正在跟進處理這些問題。
左右為難的PR
ISSUE雖然比較多並且你很可能覺得有些毫無意義,但是畢竟他們只是用戶的提問或者給出建議,我們可以選擇是否接受。
但是PR其實是比較尷尬的問題,很多用戶的PR很可能是對你的代碼進行了很大的改動,有時候這些改動你其實並不願意接受。但是有的PR,用戶花了精力和心思對你的代碼進行了大面積的改造(至少在他們心裡,這些改造是非常好的)。
這種情況下,大家都會感覺到進退兩難,如果接受PR,可能代碼有些地方就和你預想的越來越偏,如果不接受,就顯得不近人情。這種情況,我也沒有想好非常好的對策,目前我的策略,是嘗試做一個冷血無情的。如果與這個提PR的用戶還有很多交流,那就儘量用你對項目的看法和他進行交流,讓他按照你的要求更改,或者是讓她自己fork你的項目,自成一派。
像一些大型的項目,它們也有很多PR沒有被接受,且長時間擱置在那邊,例如SpringBoot
https://github.com/spring-projects/spring-boot/pulls