代码仓活跃度评分
Title
代码仓活跃度评分
Patlet
问题
内源项目应以何种顺序呈现?典型的排名指标,如GitHub星数、复刻(fork)数、提交数、代码行、最后更新,都不足以简明地表明项目的活动。
活跃的项目有很多吸引力,但也有相当新的和热情的项目,需要新的贡献者,应该比活动很少或处于维护模式的成熟项目排名更高。
为了给项目的活动水平定义一个可靠的、通用的分数,我们需要一个从几个KPI中得出的新指标。 它可以被用来根据项目的活动水平进行分类排序。
故事
当内源实践了很长时间,或者规模超过了一定数量的项目(比方说50个,给一个有意义的门槛),就很难找到目前最流行和最活跃的内源项目。存在了很长时间的项目是众所周知的,但可能不再是非常活跃的。另一方面,相当新的项目还没有声誉或活跃的社区。
内源项目列表不应该被认为是一个静态资源,而是一个发现和探索新的和活跃的项目的令人兴奋的地方,就像一个新闻页面首先列出当天最有趣的话题一样。因此,当项目的顺序定期更新,并根据项目的受欢迎程度和活动情况而改变时,这是很有好处的。
这些考虑导致了第一个计算代码库活跃度评分的原型,它的效果出乎意料地好,并根据项目的活动提供不断变化的排名顺序。
背景
约束
通过查询GitHub的API可以自动获取到和代码开发相关的关键绩效指标。那么如何评价,代码质量、良好文档的可用性,或者使项目成为一个有趣的贡献场所的活跃和互助的社区呢?
这些 "软"的关键绩效指标必须手动或半自动地添加到计算中,并得出分数。如果有工具可以为代码库提供更多的背景,如代码覆盖率报告,它们可以很容易地被加入。
素描
解决方案
代码仓活跃评分是一个数值,代表内源项目的(GitHub)活跃度。它是由GitHub星数、关注和复刻等代码仓库统计数据自动得出的,并可以用其他工具或人工评估的KPI来进行补充。
此外,它还考虑了活动参数,如 repo 的最后更新和创建日期,以便为具有大量吸引力的年轻项目提供助力。 拥有贡献指南、积极参与的统计数据和问题(公共backlog)的项目也会获得更高的排名。
下面的代码假设变量repo
包含一个从GitHubsearch
API获取的实体,participation
对象包含一个来自GitHubstats/participation
API的实体。
// 从标星、关注、提交和问题中计算出一个虚拟的内源分数
function calculateScore(repo) {
// 初始分值为50分,作为GitHub KPI(复刻、观察者、标星)较低的活跃仓库一个的起点
let iScore = 50;
// 权重:复刻和关注最多,然后是星标,对没有关闭的问题也加一些小分
iScore += repo.forks_count * 5;
iScore += (repo.subscribers_count ? repo.subscribers_count : 0);
iScore += repo.stargazers_count / 3;
iScore += repo.open_issues_count / 5;
// 在过去3个月内更新:给总分增加一个0...1的奖励乘数(1=今天更新,0=100天以前更新)
let iDaysSinceLastUpdate = (new Date().getTime() - new Date(repo.updated_at).getTime()) / 1000 / 86400;
iScore = iScore * ((1 + (100 - Math.min(iDaysSinceLastUpdate, 100))) / 100);
// 评估过去3个月的参与统计
repo._InnerSourceMetadata = repo._InnerSourceMetadata || {};
if (repo._InnerSourceMetadata.participation) {
// 平均提交量:为总分增加一个0...1的奖励乘数(1=每周提交量大于10,0=每周提交量小于3)
let iAverageCommitsPerWeek = repo._InnerSourceMetadata.participation.slice(-13).reduce((a, b) => a + b) / 13;
iScore = iScore * ((1 + (Math.min(Math.max(iAverageCommitsPerWeek - 3, 0), 7))) / 7);
}
// 加分计算
// 所有在前一年更新的资源库都将获得最大1000的加分,并按上次更新后的天数递减
let iBoost = (1000 - Math.min(iDaysSinceLastUpdate, 365) * 2.74);
// 根据资源库的创建日期,逐步缩小加分的规模,与 "真实 "的参与统计相混合
let iDaysSinceCreation = (new Date().getTime() - new Date(repo.created_at).getTime()) / 1000 / 86400;
iBoost *= (365 - Math.min(iDaysSinceCreation, 365)) / 365;
// 在总评分中加分
iScore += iBoost;
// 给予有意义的描述的项目以50的静态加分
iScore += (repo.description?.length > 30 || repo._InnerSourceMetadata.motivation?.length > 30 ? 50 : 0);
// 给予有贡献指南(CONTRIBUTING.md)文件的项目以100的静态加分
iScore += (repo._InnerSourceMetadata.guidelines ? 100 : 0);
// 为非常活跃的项目建立一个对数表(不限,但稳定在5000左右)
if (iScore > 3000) {
iScore = 3000 + Math.log(iScore) * 100;
}
// 最终得分是一个从0开始的四舍五入值(减去初始值)
iScore = Math.round(iScore - 50);
// 为元数据添加分数
repo._InnerSourceMetadata.score = iScore;
return iScore;
}
结果
贡献者可以自由地将他们的一部分时间投入到内源项目中。他们可以选择为一个他们在常规团队中依赖的项目做出贡献。然而,他们也可以根据自己的兴趣和个人发展目标,选择为一些完全不同的项目做贡献。
项目可以按照资源库活动得分进行分类和展示,在向潜在的新贡献者展示项目的门户中给出一个有意义的顺序。分数可以即时计算,也可以在后台工作中计算,定期评估所有项目并存储结果列表。
原理
仓库活跃评分是一个基于GitHub API的简单计算。它可以完全自动化,并容易适应新的需求。
已知实例
状态
作者
致谢
感谢 InnerSource Commons社区光速提供的建议,以及大量有益的意见,不断完善这个模式。特别感谢:
翻译校对