fox5t4r/My-CTF-Challenge

GitHub: fox5t4r/My-CTF-Challenge

一个通过 GitHub Issue 表单和 Actions 自动化 Git 子模块添加、验证与更新流程的仓库模板。

Stars: 0 | Forks: 0

# 子模块集合模板 **English** | [한국어](README_KR.md) [![使用此模板](https://img.shields.io/badge/Use%20this-template-2ea44f?logo=github)](../../generate) 一个 GitHub 仓库模板,用于将多个 Git 仓库作为子模块进行集中管理。 无需在每次添加子模块时手动编辑 `.gitmodules`、gitlink 和路径,用户可以通过 Issue 表单提交仓库和目标路径。GitHub Actions 会验证该请求并自动创建 pull request。 ## 功能 - 通过 Issue 表单接收仓库和父级路径 - 根据仓库名称生成最终的目录名 - 可选择覆盖目录名和跟踪的 branch - 验证仓库的可访问性和 branch 是否存在 - 检测重复的仓库和重复的路径 - 支持 Unicode、空格、撇号、分号及类似的路径字符 - 在 issue 评论中显示验证错误和最终路径 - 仅在拥有写入权限的维护者评论 `/approve` 后才创建 pull request - 可从 Actions 页面手动更新所有子模块或选定的单个子模块 - 仅当有更新的 commit 可用时才创建更新 pull request - 可选使用单独的 token 访问私有 GitHub 仓库 - 使用无依赖的纯 Node.js,无需安装步骤 ## 工作流 ``` Submit the Issue Form ↓ Validate repository, path, and duplicates ↓ Preview the final path in an issue comment ↓ A maintainer comments /approve ↓ Create a branch and pull request for the submodule ↓ Review and merge ``` 手动更新的工作方式如下: ``` Actions → Update submodules → Run workflow ↓ Resolve the tracked branch for all or one submodule ↓ Update gitlinks to the latest remote commits ↓ Create a pull request only when changes exist ↓ Review and merge ``` ## 快速开始 ### 1. 从模板创建仓库 1. 点击 `Use this template`。 2. 选择 `Create a new repository`。 3. 选择仓库名称和可见性。 4. 创建仓库。 GitHub 会将此模板的文件和目录结构复制到新仓库中。 ### 2. 启用 Issues 打开: ``` Settings → General → Features → Issues ``` 如果 `Issues` 被禁用,请将其启用。 对于受管理的集合,请在 `Issues` 旁边的下拉菜单中选择 `Collaborators only`。这可以防止外部用户开启请求 issue 并触发预览工作流运行。此限制适用于仓库中的每个新 issue,而不仅仅是子模块请求表单。请参阅 [GitHub 的 issues 设置文档](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/disabling-issues)。 ### 3. 授予 GitHub Actions 写入权限 打开: ``` Settings → Actions → General → Workflow permissions ``` 启用: - `Read and write permissions` - `Allow GitHub Actions to create and approve pull requests` 如果没有这些设置,请求验证仍可运行,但推送 branch 或创建 pull request 可能会失败。 ### 4. 请求子模块 打开: ``` Issues → New issue → Add a submodule ``` 表单包含以下字段: | 字段 | 必填 | 描述 | | --- | --- | --- | | Repository | 是 | `owner/repository` 或 GitHub HTTPS URL | | Parent path | 是 | 子模块的父目录。仓库根目录请使用 `.` | | Directory name | 否 | 留空时使用仓库名称 | | Branch | 否 | 留空时使用远程仓库的默认 branch | | Confirmation | 是 | 确认已对仓库和父级路径进行了审查 | 示例: ``` Repository: example/example Parent path: collections Directory name: example Branch: main Confirmation: checked ``` 生成的路径: ``` collections/example ``` 创建或编辑 issue 会触发一个工作流,该工作流会将验证结果和最终路径作为评论发布。 ### 5. 批准请求 在审查成功的验证结果后,拥有 `write`、`maintain` 或 `admin` 权限的用户可以评论: ``` /approve ``` 工作流会验证批准者的仓库权限,并再次验证最新的 issue 内容。然后它会: 1. 创建一个 `submodule/issue-` branch。 2. 运行 `git submodule add`。 3. 提交 `.gitmodules` 和 gitlink。 4. 创建一个 pull request。 5. 在 issue 上发布 pull request 的 URL。 pull request 的正文包含 `Closes #`,因此合并该请求也会关闭对应的请求 issue。 ## 手动更新子模块 要将已注册的子模块更新为其最新跟踪的 commit,请打开: ``` Actions → Update submodules → Run workflow ``` 可选的 `path` 输入项用于控制更新范围: | 输入项 | 行为 | | --- | --- | | 为空 | 更新在 `.gitmodules` 中注册的每个子模块 | | 精确路径 | 仅更新选定的子模块 | 示例路径: ``` collections/example ``` 该值必须与 `.gitmodules` 中的 `path` 条目完全匹配。如果缺失或拼写错误,工作流将失败并在日志中列出可用路径。 更新工作流使用以下规则选择目标 commit: 1. 当子模块在 `.gitmodules` 中有 `branch` 条目时,更新到该 branch 上的最新 commit。 2. 否则,更新到远程仓库默认 branch 上的最新 commit。 例如,此子模块跟踪 `main`: ``` [submodule "collections/example"] path = collections/example url = https://github.com/example/example.git branch = main ``` 当存在更新时,工作流会创建一个 branch 和 pull request,如下所示: ``` submodule/update- ``` pull request 会列出每个已更改子模块的先前 commit 和更新后的 commit。当每个选定的子模块都已是最新状态时,则不会创建任何 branch 或 pull request;结果仅显示在工作流摘要中。 ## 支持的仓库输入 默认配置仅接受 GitHub HTTPS 仓库。 这些输入会被归一化为同一个仓库: ``` example/example https://github.com/example/example https://github.com/example/example.git ``` 归一化结果: ``` https://github.com/example/example.git ``` SSH URL、`file://` URL、内嵌凭据、查询字符串和 fragments 都会被拒绝。 ## 限制仓库所有者 使用 `scripts/submodule-manager.mjs` 顶部的 `whitelist_owner` 数组来限制可以添加的仓库所有者。 默认的空数组允许所有所有者: ``` export const whitelist_owner = []; ``` 添加所有者名称以仅允许选定的用户或组织: ``` export const whitelist_owner = [ 'example', 'example-org', ]; ``` 当数组中至少包含一个值时,仅接受由列表中所有者拥有的仓库。所有者匹配不区分大小写,这与 GitHub 的行为一致。 ``` example/example → allowed example-org/example → allowed other-owner/example → rejected ``` 对于完整的 HTTPS URL,hostname 之后的第一段路径将被视为所有者。 ## 配置 在 `.github/submodule-manager.json` 中自定义行为: ``` { "allowed_hosts": [ "github.com" ], "authenticated_hosts": [ "github.com" ], "allow_root": true, "portable_paths": true, "prevent_duplicate_repository": true, "prevent_case_insensitive_path": true } ``` ### `allowed_hosts` 请求可以使用的 HTTPS Git 主机列表。 ``` { "allowed_hosts": [ "github.com", "git.example.com" ] } ``` `owner/repository` 简写总是解析为 `github.com`。若要使用其他主机,请提供完整的 HTTPS URL。 ### `authenticated_hosts` `allowed_hosts` 的子集,可以接收 `SUBMODULE_TOKEN`。默认仅包含 `github.com`;请勿将公开的自定义主机放入此列表。仅当 token 适用于特定的私有自定义主机时,才将其显式添加到此列表中。 ``` { "allowed_hosts": [ "github.com", "git.example.com" ], "authenticated_hosts": [ "github.com" ] } ``` ### `allow_root` 当设为 `true` 时,用户可以输入 `.` 作为父级路径,以便在仓库根目录下添加子模块。 ### `portable_paths` 当设为 `true` 时,验证器会拒绝可能导致 Windows 上无法 checkout 的保留名称和字符。Unicode、空格、撇号和分号仍然受支持。 ### `prevent_duplicate_repository` 当 `.gitmodules` 中已包含相同的仓库 URL 时,拒绝该请求。GitHub URL 会在对大小写进行归一化并处理可选的 `.git` 后缀之后再进行比较。 ### `prevent_case_insensitive_path` 拒绝在不区分大小写的文件系统上会发生冲突的路径。 例如,当 `Collections/Example` 已经存在时,`collections/example` 也会被视为重复。 ## 私有子模块 默认的 `GITHUB_TOKEN` 仅限于集合仓库使用,可能无法读取其他私有仓库。 要添加私有仓库,请在集合仓库中创建一个 `SUBMODULE_TOKEN` Actions secret。对于不接受 `x-access-token` 作为 HTTPS 用户名的主机,还需使用所需的用户名创建 `SUBMODULE_TOKEN_USERNAME`: ``` Settings → Secrets and variables → Actions → New repository secret ``` 建议的权限设置: - 使用 fine-grained personal access token。 - 仅授予目标私有仓库的 `Contents: Read-only` 权限。 - 请勿授予集合仓库的写入权限。 - 使用尽可能短的有效期。 该 token 仅在获得写入权限的 `/approve` 进行重新验证和添加目标子模块之后,以及在 `authenticated_hosts` 上进行手动更新期间使用。公开的 issue 预览绝不会收到此 token,因此在经过授权的协作者批准之前,私有仓库可能会显示为无法访问。目标 Git 命令在应用此 token 之前,会显式丢弃集合仓库的 checkout 凭据。集合仓库中的 branch 会使用默认的 `GITHUB_TOKEN` 进行推送。 ## 验证规则 请求必须满足以下所有条件: - 使用位于允许主机上的 HTTPS 仓库 - 使用该主机的默认 HTTPS 端口 - 指向可访问的仓库 - 在指定 branch 时,该 branch 必须存在 - 包含从 Issue 表单中勾选的确认信息 - 使用相对路径 - 不包含 `.` 或 `..` 路径段 - 避开 `.git` 内部的路径 - 不包含控制字符或换行符 - 不与 `.gitmodules` 中已注册的等效 HTTPS、SSH 或 scp 风格仓库重复 - 在不区分大小写的文件系统上不与已跟踪的路径发生冲突 - 不会穿越现有父级路径中的符号链接 批准操作会将审查时的 branch 和 commit 绑定到 pull request 中暂存的 gitlink。如果远程仓库在审查后发生移动,工作流将 checkout 所审查的 commit,或者在未推送 pull request 的情况下直接失败。 用户输入永远不会被拼接到 shell 命令中。验证之后,Node.js 脚本会通过 `child_process` 将值作为独立参数传递。 该管理器仅使用 Node.js 标准库。工作流调用 GitHub 托管的 `ubuntu-latest` runner 上已安装的 Node.js 版本,且不会运行 `actions/setup-node`、`npm install` 或 `npm ci`。实际的工作流耗时通常主要来自于 runner 启动和远程 Git 操作。 ## 发布此模板 将此项目推送到 GitHub 后,在以下位置启用模板模式: ``` Settings → General → Template repository ``` 启用后,GitHub 将在仓库顶部显示 `Use this template` 按钮。 此 README 顶部的徽章使用的是相对链接,因此重命名模板仓库无需更新徽章 URL。 ## 项目结构 ``` . ├── .github │ ├── ISSUE_TEMPLATE │ │ ├── add-submodule.yml │ │ └── config.yml │ ├── workflows │ │ ├── approve-submodule-request.yml │ │ ├── preview-submodule-request.yml │ │ └── update-submodules.yml │ └── submodule-manager.json ├── scripts │ └── submodule-manager.mjs ├── LICENSE ├── README.md └── README_KR.md ``` ## 注意事项 - 工作流创建的 pull request 永远不会自动合并。 - 编辑请求 issue 会刷新其预览评论。 - 提交 `/approve` 时会再次验证最新的 issue 内容。 - 如果该 issue 的自动化 branch 已经存在 pull request,则不会再创建另一个。没有 pull request 的孤立 branch 会被保留,并且重试会使用新的特定运行 branch。 - 使用默认 `GITHUB_TOKEN` 创建的 pull request 可能无法触发其他工作流。如果在创建 pull request 之后必须运行额外的 CI,请使用 GitHub App 或其他 token。 ## 许可证 MIT License
标签:MITM代理, 自定义脚本