开源管理门户
这个应用程序是微软开源工程体验的核心。作为后端应用,它管理着多种类型的企业开源元数据、存储库和项目的历史意图的真实来源,提供丰富的前端界面,并为合作伙伴团队提供一系列API。
虽然我们更喜欢原生的GitHub体验,但在显示某些信息和提高权限及元数据透明度方面,尤其是在GitHub这种没有可扩展用户界面的平台上,我们最终会使用并引导人们使用这个开源管理门户来获取所需信息。
在微软,有5万名工程师正在使用这个门户的某个版本作为他们开源工程体验的一部分。然而,微软确实有一些"公司特定"的扩展,包括一个独立的React前端客户端,目前并不包含在这个存储库中。而且...是的,如果我们今天重新开始,我们可能会将其做成一个Next.js或类似的项目。
这个应用程序的核心功能和特性包括:
- 链接GitHub账户 ⛓️ 用于企业使用
- 工程师自助加入GitHub组织 🙋
- 创建和管理GitHub开源存储库 👩💻
- 显示透明的信息、指标和公司特定数据 关于我们GitHub开源存在的权限、访问、元数据、意图,特别是跨组织视图和搜索索引
- 人员库存 👨🦳🧑🚀🧒🏽 帮助人们将GitHub公共登录与企业身份关联
- 拦截分叉和新存储库 🔐 以注入合规和审批流程
- 禁用和启用 🔑 GitHub存储库的体验
- 开源存储库、团队和组织的即时(JIT)访问 🚪,遵循最小权限访问原则
- 存储库、团队、组织的Sudo ⚡️ 功能,以移除持久的广泛所有权和管理员权限
- 托管API 🍽️ 用于创建存储库、大规模组织访问链接数据和报告
- 后台作业 👷♂️ 维护最终一致性、运行任务、收集指标和准备OKR
- 带有上下文的团队加入请求/批准 🚪 超越GitHub体验的构建
- 自动离职 🛶 当人们寻求新机会时
在微软,额外的功能包括:
- 发布项目前的业务和法律审批 🧑⚖️
- 请求贡献审核 ✍🏾 在政策范围内
- 服务树和直接所有者库存 🌳 在可用时显示存储库的负责所有权信息
- 托管内部文档 📚 在aka.ms/opensource
- 托管opensource.microsoft.com的部分API 🌍 展现微软的开源存在
管理门户旨在快速、高效,不妨碍工程师完成重要工作,强调_无情自动化_和_授权_。
大多数体验最终是一致的;然而,诸如加入团队、组织、sudo操作等操作行为在请求时是完全一致的。
实施细节和更多文档
请查看docs/
子文件夹,包括docs/index.md。
API
有关当前API的信息,请查看docs/api.md文件。
用于学习的应用程序技术栈
作为一个TypeScript/Node.js后端应用程序,配有React前端,管理门户也为微软的工程系统团队提供了了解非.NET技术栈应用可能有的体验的学习机会。1ES+OSPO团队合作,基于这个开源存储库的一个分支来发布应用程序。
截至2022年,后端站点由Azure App Service托管,使用Linux容器,而后台定时作业和守护进程在Azure Kubernetes Service (AKS)集群中运行。所有容器都基于CBL Mariner发行版构建。
该应用最初是在充满"回调地狱"的古老JavaScript时代作为黑客马拉松项目开始的,并已经发展到使用第三方promise库,再到原生ECMAScript promises,最后到TypeScript。因此,它既显示了年代感,又很有趣。
Web应用认证
该站点的主要认证是面向企业用户的Azure Active Directory。
次要认证是GitHub。这允许不使用GitHub的用户完全探索站点、链接并保持高效。
理论上,开源朋友们,这个项目可以做得更具扩展性。过去,我们曾为主要方面原型化了Google认证,例如。欢迎贡献!
API可以使用JWT或在某些情况下使用活动的Web应用会话,由React前端使用。
配置 ⛳️
存在许多功能标志。
作业 💼
请查看docs/jobs.md
服务依赖
- GitHub组织
- 托管环境
- 用于最终一致性工作和维护定时作业的后台作业环境
- 用于近实时处理的守护进程托管
- 队列系统
- 缓存系统或多层缓存实现
- Azure Active Directory和Microsoft Graph
- 用于发送邮件的电子邮件服务
- 可选的洞察或遥测系统
真实来源存储 🧑⚖️
后端在您选择的数据存储中维护存储库、链接和一般合规信息的关键元数据。后端原生支持Azure Storage、Azure Table、Azure CosmosDB和Postgres。
在微软,我们目前使用Postgres作为真实来源,包括:
- GitHub组织配置
- 企业GitHub存储库元数据
- 企业身份到GitHub登录的链接
- 合规元数据(启用/禁用的存储库)
尊重GitHub API
为了对GitHub友好,我们努力高效和公平地使用GitHub API。我们尽可能多地缓存,并有一个基于GitHub条件请求最佳实践的原生概念用于GitHub应用:只要可能,我们都会发送请求的e-tag
,并在许多类型的操作中使用我们的缓存。
对于长时间的多页GitHub REST API v3响应,我们会维护这些响应的缓存,并在后台慢慢重建,因为对于大多数视图来说,站点最终是一致的。
对于操作性工作,使用实时API调用以在处理授予访问权限或管理超级用户功能的访问权限时保持准确和安全。
缓存
主要缓存层由CosmosDB文档支持,采用混合方法,较大的文档回退到Azure Storage(blob)。开源用户也支持Redis。
后台事件处理消防水管和定时作业
至少有2个持续运行的单实例守护进程集和许多定时作业,保持站点高效、最新,并收集重要信息。
守护进程:
- 消防水管:从队列处理webhook事件,实现最终一致性并响应GitHub事件,涉及合规/审计/规模/管理
- 即时:JIT撤销、审计日志事件收集和分析
定时作业示例:
- 确保缓存偶尔被预填充
- 提醒人们设置或删除存储库
- 自动删除在时间窗口内未设置的存储库
- 禁用不合规的存储库
- 收集数据和指标用于报告和用户界面体验
- 备份链接数据
- 为OKR准备统计数据
关于消防水管的详细信息
虽然原始门户对于非常小的GitHub存在运作良好,但它的设计理念是缓存会填满,同时尊重GitHub REST API通过使用条件请求,并且最终保持一致。 然而,REST API v3(非GraphQL客户端)的每页结果最大数量为100条,如果你有成千上万的任何内容,这将非常痛苦。
"firehose"设计用于在应用程序内部运行,或作为处理结果的次要应用程序。在微软,我们使用服务总线来处理来自GitHub的webhook事件,因为我们在其他地方有一个强大的webhook接收机制。firehose作为一个守护进程运行,从队列中提取数据并努力保持"查询缓存"中的信息比REST API在某些情况下更新。
这改进了以下方面:
- 用户对他们被添加到并有权访问的组织、仓库、团队的视图
- 跨组织的视图和查询
firehose和查询缓存不用于重要或身份验证类型的场景:
- 查询缓存不用于做出权限决定
- 查询缓存不用于授权访问管理功能
我们曾经设计了一个/webhook
端点的想法,并在处理简单应用程序托管的钩子之前验证webhook签名,但现在它在微软有些问题并被禁用了。
开发准备、构建、部署
安装Node包
确保包含开发依赖项。
默认资源包是一个非常古老的Bootstrap和jQuery应用,理论上为网站提供基本皮肤、网站图标、图形等。然而,它真的非常非常旧。微软放弃了默认资源包,使用了一套不同的资源,所以你已经被轻微警告过了。
定义的默认资源包的main
模块应该解析为要提供内容的路径。由于默认版本使用[古老的]Grunt来构建资源,它返回__dirname
+ /public
,这是Grunt的输出/构建位置。
npm install
cd default-assets-package
npm install
构建
npm run build
如果你更改了某些内容,需要重新构建默认资源包。参见静态站点资源
Codespaces说明
你可能想使用预定义的环境来节省设置多个变量的时间,请按照以下路径之一操作:
- 使用GitHub Codespaces帐户级别的秘密存储你的环境变量
- 在Codespace环境中使用克隆仓库上一级目录中的
.env
文件 - 在devcontainer启动后配置环境变量
- 使用GitHub Codespaces仓库特定的秘密
无论是作为秘密还是在根目录的../env
中,设置
CONFIGURATION_ENVIRONMENT
:development
(或类似)
然后,你还需要确保在重定向到运行的Codespaces环境时身份验证能够正常工作。
GitHub身份验证
你需要使用自己的GitHub应用程序,并使用其客户端ID和客户端密钥进行身份验证。配置你的帐户特定的Codespace秘密。
CODESPACES_GITHUB_AUTHENTICATION_ENABLED
: 设置为1
以启用CODESPACES_GITHUB_CLIENT_ID
: 客户端IDCODESPACES_GITHUB_CLIENT_SECRET
: 客户端密钥
根据需要为你的fork和/或此仓库配置秘密。重定向URL将动态生成并包含在启动调试输出中。确保主机名是GitHub应用程序的适当回调URL。
企业托管用户模拟/覆盖
由于底层仓库和Codespace可能托管在GHEC EMU中,你还需要使用调试时模拟功能来在GitHub回调后覆盖EMU用户信息,使用你的GitHub.com帐户。
为了便于使用,提供了一个初始模拟覆盖功能,它只会覆盖GitHub EMU响应:
CODESPACES_IMPERSONATE_OVERRIDE_EMU_ENABLED
: 在你的环境中设置为1
以允许CODESPACES_IMPERSONATE_OVERRIDE_EMU_LOGIN
: 设置为仅在EMU用户进行身份验证时使用的登录名。主要模拟功能在此之后仍将使用。
AAD身份验证
在适当的租户中配置你的AAD应用程序。
CODESPACES_AAD_AUTHENTICATION_ENABLED
: 设置为1
以启用- 根据需要为你的环境设置其他AAD变量:
AAD_CLIENT_ID
AAD_CLIENT_SECRET
- ...
私有工件
微软内部的这个项目分支使用私有Azure工件源来引入额外的组件和库。这些目前不适用于开源上游,应该被排除。
构建Docker镜像
docker build -t opensource-management-portal .
运行(开源说明)
本节来自开源社区
最简单的运行方式是使用docker-compose设置。这也会启动postgres和redis组件。docker-compose设置依赖于2个环境文件和1个json文件:
- .docker.env
- .secrets.env
- env-orgs.json
确保复制.secrets.env.example和env-orgs.json.example文件,并提供配置值。
cp .secrets.env.example .secrets.env
cp env-orgs.json.example env-orgs.json
# 为.secrets.env和env-orgs.json提供配置值
docker-compose up
如果你希望在本地机器上运行所有内容(redis,postgres),你可能想使用以下方法。
# 确保redis和postgres在localhost上运行
source .secrets.env
source .local.env
npm run start
故障排除
如果docker镜像无法启动,你可以使用交互式shell会话调试镜像。这允许你浏览文件夹,更新文件以测试内容,并运行门户。
$ docker run --rm -it --env-file .secrets.env --env-file .docker.env --entrypoint /bin/sh opensource-management-portal
/usr/src/repos $ ls
app.js data lib package.json tsconfig.tsbuildinfo webhooks
app.js.map entities localEnvironment.js routes user
bin features localEnvironment.js.map test utils.js
business github middleware transitional.js utils.js.map
config jobs node_modules transitional.js.map views
/usr/src/repos $ npm run start-in-container
测试
这个项目基本上几乎没有测试,并且希望开始更好地使用Jest。糟糕。多个黑客马拉松的组合,加上对GitHub的生产依赖导致了不良债务...
最基本的本地开发环境
如果你在克隆仓库的目录上方放置一个JSON文件.env
(以防止意外或在编辑器中将秘密提交到你的仓库),你可以配置以下极简工作集来使用该应用程序。
中央操作令牌是一个个人访问令牌,是被管理的GitHub组织的组织所有者。
DEBUG_ALLOW_HTTP=1
GITHUB_CENTRAL_OPERATIONS_TOKEN=用于应用程序的github令牌
GITHUB_ORGANIZATIONS_FILE=../../env-orgs.json
GITHUB_CLIENT_ID=你的客户端ID
GITHUB_CLIENT_SECRET=你的客户端密钥
GITHUB_CALLBACK_URL=http://localhost:3000/auth/github/callback
AAD_CLIENT_ID=你的企业应用程序ID
AAD_REDIRECT_URL=http://localhost:3000/auth/azure/callback
AAD_CLIENT_SECRET=企业应用程序的密钥
AAD_TENANT_ID=你的租户ID
AAD_ISSUER=https://sts.windows.net/你的租户ID/
在这种模式下,使用内存提供程序,包括模拟的Redis客户端。请注意,这意味着配置了内存提供程序的大型GitHub组织可能会成为令牌使用的噩梦,因为每次没有Redis缓存的应用程序执行都会导致GitHub元数据100%缓存未命中。考虑配置开发或本地Redis服务器以保留缓存数据。
当我们迁移到下一个主要语义版本的Node Redis库时,内置的Redis模拟可能会被移除。
协作
这个项目始于一场黑客马拉松...所以多年后仍在成长中。由于这在技术上是一个后端Web应用程序,并包含一些服务器生成的用户界面,该项目最初并不是设计为可以开箱即用的东西,但...它是可能的。 为了协作进行扩展和改进,请先在问题中同步,以便我们能够提出最佳方法。
再次强调,由于Microsoft剥离了大部分的routes/
并在此应用中使用React前端,routes/
和Pug渲染可能已经...非常陈旧了。
希望这个单体应用至少能成为一个有趣的学习机会,让我们了解JavaScript前端如何在陈旧的古老应用中演变!
待完成工作(开源项目)
- 支持更多有趣的云和数据提供商
- 支持其他身份验证技术
- 添加测试
- 增加更多测试
- 将前端UI作为开源项目向全世界发布
- 继续尽可能重构剔除Microsoft特有的内容
项目起源
JWilcox在2015年的一篇文章和2019年的后续文章"从2,000扩展到25,000"中介绍了这个项目。
开源中心的概念最初由Microsoft的一个子公司和早期的开源项目办公室原型开发,旨在明确Microsoft文化变革中的开源体验、文档和指南,以更加开放的方式工作、发布项目并将一切联系起来。
同时,GitHub功能还很基础,有必要将GitHub工程系统自动化并实现自助服务,以适应企业规模。当Azure成为Microsoft首个批准使用GitHub的组织时,这个门户扩展了访问权限,并为GitHub环境构建了防护栏。
许可证
贡献
本项目欢迎贡献和建议。大多数贡献要求您同意贡献者许可协议(CLA),声明您有权并确实授予我们使用您贡献的权利。有关详细信息,请访问https://cla.opensource.microsoft.com。
当您提交拉取请求时,CLA机器人会自动确定您是否需要提供CLA,并适当地修饰PR(例如,状态检查、评论)。只需按照机器人提供的说明操作即可。您只需在所有使用我们CLA的仓库中执行一次此操作。
本项目已采用Microsoft开源行为准则。有关更多信息,请参阅行为准则常见问题解答或联系opencode@microsoft.com提出任何其他问题或意见。
商标
本项目可能包含项目、产品或服务的商标或标志。Microsoft商标或标志的授权使用必须遵循Microsoft商标和品牌指南。在本项目的修改版本中使用Microsoft商标或标志不得造成混淆或暗示Microsoft赞助。任何第三方商标或标志的使用均受这些第三方的政策约束。