range42/gh-repo-organizer

GitHub: range42/gh-repo-organizer

一款用于批量克隆 GitHub 组织仓库并执行标准合规性与安全扫描审计的 Bash 自动化工具。

Stars: 2 | Forks: 0

# GitHub 组织仓库克隆工具 **GitHub 组织仓库克隆工具 - 自动克隆并审计 GitHub 组织的所有仓库,并进行全面的标准合规性检查。** 一个强大的 bash 脚本,用于克隆和审计 GitHub 组织的所有仓库。自动将仓库分类到公共和私有目录中,并对仓库的标准合规性进行全面的完整性检查。 ## 功能特性 - **批量克隆仓库**:从任何 GitHub 组织克隆所有可访问的仓库 - **智能分类**:自动将公共和私有仓库分离到专门的目录中 - **自动更新**:使用 `git pull` 自动更新现有仓库 - **感知身份验证**:无论是否通过 GitHub 身份验证均可工作(未认证时仅限公共仓库) - **全面的完整性检查**:逐行输出审计仓库的标准文件和最佳实践 - **仓库过滤**:对特定仓库运行完整性检查以便进行集中分析 - **灵活的配置**:基于环境变量的配置,易于自定义 - **健壮的错误处理**:通过 HTTPS 回退优雅地处理克隆失败的情况 - **彩色输出**:清晰、彩色的终端输出以提供更好的可视性 ## 快速开始 1. **安装前置条件**: # 安装 GitHub CLI brew install gh # macOS # 或者 sudo apt install gh # Ubuntu/Debian # 安装 jq 用于 JSON 解析 brew install jq # macOS # 或者 sudo apt install jq # Ubuntu/Debian 2. **配置脚本**: # 创建配置文件 cp config.env.example config.env # 编辑你的组织名称 vim config.env 3. **运行脚本**: # 克隆所有仓库 ./gh_repo_cloner.sh # 对所有仓库执行完整性检查 ./gh_repo_cloner.sh --sanity-check # 检查特定仓库 ./gh_repo_cloner.sh --sanity-check my-repo-name ## 前置条件 - **GitHub CLI (`gh`)** - 用于列出仓库和进行身份验证 - **Git** - 用于克隆仓库 - **jq** - 用于解析 JSON - **Bash 4.0+** - 用于执行脚本 ## 配置 创建一个包含以下变量的 `config.env` 文件: ``` # 必填:组织名称 ORG="your-organization-name" # 可选:目录路径(显示默认值) PUB_DIR="./pub" PRIV_DIR="./priv" # 可选:输出颜色(显示默认值) RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color ``` ### 配置选项 | 变量 | 描述 | 默认值 | 是否必填 | |----------|-------------|---------|----------| | `ORG` | GitHub 组织名称 | - | 是 | | `PUB_DIR` | 公共仓库目录 | `./pub` | 否 | | `PRIV_DIR` | 私有仓库目录 | `./priv` | 否 | | `RED`, `GREEN` 等 | 终端颜色 | ANSI 代码 | 否 | ## 用法 ### 基本命令 ``` # 显示帮助 ./gh_repo_cloner.sh --help # Clone 所有 repositories ./gh_repo_cloner.sh # 对所有 repositories 执行 sanity checks ./gh_repo_cloner.sh --sanity-check # 对特定 repository 执行 sanity check ./gh_repo_cloner.sh --sanity-check my-repository-name # 替代语法(简写形式) ./gh_repo_cloner.sh -s my-repository-name ``` ### 命令行选项 | 选项 | 描述 | |--------|-------------| | `-s, --sanity-check [REPO]` | 对仓库执行完整性检查以确认常见文件。可选择指定要检查的特定仓库名称 | | `-h, --help` | 显示帮助信息并退出 | ### 使用示例 ``` # 从该组织 Clone 所有 repositories ./gh_repo_cloner.sh # 对所有 repositories 运行全面的 sanity checks ./gh_repo_cloner.sh --sanity-check # 仅检查 "range42-inventory" repository ./gh_repo_cloner.sh --sanity-check range42-inventory # 仅检查 "my-backend-api" repository(简写形式) ./gh_repo_cloner.sh -s my-backend-api ``` ## 仓库过滤 该脚本支持将完整性检查过滤到特定仓库,这对于以下情况非常有用: - **集中分析**:检查单个仓库,不受其他仓库的干扰 - **快速验证**:验证特定仓库上的修复 - **新人入职**:向新开发人员展示特定项目的标准 - **CI 集成**:在自动化工作流程中验证特定仓库 ### 过滤行为 - **自动发现**:脚本会在 `./pub` 和 `./priv` 目录中搜索指定的仓库 - **错误处理**:如果未找到该仓库,它会列出所有可用的仓库 - **精简输出**:仅显示指定仓库的结果,并提供简化的摘要 ### 过滤示例 ``` # 检查 "awesome-project" repository ./gh_repo_cloner.sh -s awesome-project # 输出仅显示该 repository 的结果: # [INFO] Checking repository: awesome-project # [INFO] awesome-project: # ✓ LICENSE # ✗ CHANGELOG # ... # [INFO] Repository checked: awesome-project # [SUCCESS] Repository has all required files! ``` ## 完整性检查 该脚本可以审计仓库是否符合通用标准和最佳实践: ### 检查的文件 | 类别 | 文件/目录 | |----------|-------------------| | **许可证** | `LICENSE`, `LICENSE.txt`, `LICENSE.md`, `COPYING`, `COPYRIGHT`(包含内容验证) | | **文档** | `README.md`, `README.txt`, `README` | | **更新日志** | `CHANGELOG.md`, `HISTORY.md`, `RELEASES.md` | | **贡献指南** | `CONTRIBUTING.md`, `CONTRIBUTING.txt` | | **安全** | `SECURITY.md`, `SECURITY.txt` | | **行为准则** | `CODE_OF_CONDUCT.md` | | **Git 配置** | `.gitignore` | | **编辑器配置** | `.editorconfig` | | **文档目录** | `docs/`, `documentation/` | | **GitHub 模板** | `.github/ISSUE_TEMPLATE/`, `.github/PULL_REQUEST_TEMPLATE.md` | ### CI/CD 检测 该脚本会自动检测各种 CI/CD 配置: - **GitHub Actions** - `.github/workflows/` - **GitLab CI** - `.gitlab-ci.yml` - **Travis CI** - `.travis.yml` - **Jenkins** - `Jenkinsfile` - **CircleCI** - `.circleci/` - **Azure Pipelines** - `azure-pipelines.yml` - **Buildkite** - `.buildkite/` - **Bitbucket Pipelines** - `bitbucket-pipelines.yml` ### LICENSE 内容验证 该脚本不仅检查是否存在 LICENSE 文件,还会验证许可证是否已正确填写。它会检测指示许可证不完整的常见模板占位符: **检测到的模板占位符:** - ``, `[year]`, `YYYY` - 年份占位符 - ``, ``, `` - 作者占位符 - ``, `` - 版权占位符 - `COPYRIGHT_HOLDER`, `AUTHOR_NAME`, `YOUR_NAME`, `YOUR NAME` - 常见的模板变量 **检测到的 LICENSE 文件变体:** - 标准名称:`LICENSE`, `LICENSE.txt`, `LICENSE.md`, `LICENSE.rst` - 大小写变体:`license`, `License` - 替代名称:`COPYING`, `COPYRIGHT`(在某些项目中很常见) - 所有检查均带有适当的文件类型验证(而非目录或符号链接) **LICENSE 状态指示符:** - **✓ LICENSE** - 文件存在且已正确填写 - **⚠ LICENSE(包含模板占位符)** - 文件存在但需要自定义 - **✗ LICENSE** - 完全缺少文件 ## 安全扫描 当你运行 `make prep_ai` 时,流水线会针对 `pub/` 和 `priv/` 仓库执行 `./helpers/3_static_scan.sh`,并自动执行基于文件的安全扫描检测。 ### 扫描器检测规则 | 触发条件 | 扫描器 | 输出文件 | |---------|---------|-------------| | 存在 `requirements.txt` | `pip-audit -r requirements.txt --format json` | `analysis/files//pip_audit.json` | | 存在 `requirements.txt` | `safety check --file=requirements.txt --json` | `analysis/files//safety.json` | | 存在 `package.json` **且**存在 `package-lock.json`、`yarn.lock` 或 `pnpm-lock.yaml` 之一 | `npm audit --json` | `analysis/files//npm_audit.json` | | 仓库中存在任何 `*.py` 文件 | `bandit -r -f json` | `analysis/files//bandit_report.json` | ### 行为与输出 - 扫描结果将作为 JSON 文件写入 `analysis/files//` 下。 - 在当前实现中,扫描是非阻塞的(`|| true`):扫描器失败不会中断整个 `prep_ai` 流水线。 - 如果仓库有 `package.json` 但没有锁文件(lock file),该工具会向 `npm_audit.json` 写入错误 JSON 负载,并向 stderr 打印警告。 ### 配置 / 退出机制 - 目前没有专用的扫描级别 CLI 标志或 `config.env` 开关来启用/禁用各个扫描器。 - 要跳过这些扫描,请运行 `make prep_ai` 以外的工作流,或修改 `helpers/3_static_scan.sh` 以实现自定义行为。 ## 示例输出 ### 仓库克隆 ``` [INFO] GitHub Organization Repository Cloner [INFO] ====================================== [SUCCESS] Authenticated with GitHub [INFO] Authenticated as: username [INFO] Organization: awesome-org [INFO] Found 25 repositories [INFO] Repository awesome-project already exists, updating... [SUCCESS] ✓ Updated awesome-project in ./pub/ [SUCCESS] ✓ Cloned new-secret-sauce to ./priv/ [ERROR] ✗ Failed to update modified-repo (may have local changes or connection issues) [SUCCESS] Cloning completed! [INFO] Summary: [INFO] Public repositories cloned: 12 [INFO] Private repositories cloned: 8 [WARNING] Failed to clone: 5 ``` ### 完整性检查结果(所有仓库) ``` [INFO] Checking public repositories in ./pub: awesome-project: ✓ LICENSE ✓ CHANGELOG ✓ CONTRIBUTING ✓ README ✓ GITIGNORE ✓ SECURITY ✓ CODE_OF_CONDUCT ✓ EDITORCONFIG ✓ DOCS ✓ ISSUE_TEMPLATES ✓ PR_TEMPLATE ✓ CI/CD legacy-tool: ⚠ LICENSE (contains template placeholders) ✗ CHANGELOG ✗ CONTRIBUTING ✓ README ✓ GITIGNORE ✗ SECURITY ✗ CODE_OF_CONDUCT ✗ EDITORCONFIG ✗ DOCS ✗ ISSUE_TEMPLATES ✗ PR_TEMPLATE ✓ CI/CD [INFO] Sanity Check Summary: [INFO] ===================== [INFO] Total repositories checked: 25 [SUCCESS] Repositories with all files: 8 [WARNING] Repositories missing files: 17 [INFO] Legend: [INFO] ✓ = File/directory present and complete [INFO] ✗ = File/directory missing [INFO] ⚠ = LICENSE present but contains template placeholders ``` ### 完整性检查结果(单个仓库) ``` [INFO] Running sanity check on repository: range42-inventory [INFO] Checking repository: range42-inventory [INFO] range42-inventory: ⚠ LICENSE (contains template placeholders) ✗ CHANGELOG ✗ CONTRIBUTING ✓ README ✓ GITIGNORE ✗ SECURITY ✗ CODE_OF_CONDUCT ✗ EDITORCONFIG ✗ DOCS ✗ ISSUE_TEMPLATES ✗ PR_TEMPLATE ✗ CI/CD [INFO] Sanity Check Summary: [INFO] ===================== [INFO] Repository checked: range42-inventory [WARNING] Repository is missing some files. [INFO] Legend: [INFO] ✓ = File/directory present and complete [INFO] ✗ = File/directory missing [INFO] ⚠ = LICENSE present but contains template placeholders ``` ## 身份验证 ### GitHub CLI 身份验证 ``` # 使用 GitHub CLI 登录 gh auth login # 检查身份验证状态 gh auth status ``` ### 不同身份验证状态下的行为 | 身份验证 | 公共仓库 | 私有仓库 | 频率限制 | |----------------|--------------|---------------|-------------| | 已认证 | 完全访问权限 | 基于权限的访问 | 5,000次/小时 | | 未认证 | 只读访问 | 无访问权限 | 60次/小时 | ## 错误处理 该脚本包含健壮的错误处理机制: - **SSH 到 HTTPS 回退**:自动使用 HTTPS 重试失败的 SSH 克隆 - **现有仓库更新**:自动为现有仓库拉取(pull)最新更改 - **权限验证**:针对访问问题提供清晰的错误消息 - **速率限制感知**:针对未认证用户发出 API 速率限制警告 - **未找到仓库**:在过滤时,提供带有可用仓库列表的有用错误消息 ## 目录结构 运行脚本后,你的目录结构将如下所示: ``` project-root/ ├── gh_repo_cloner.sh ├── config.env ├── pub/ │ ├── public-repo-1/ │ ├── public-repo-2/ │ └── ... └── priv/ ├── private-repo-1/ ├── private-repo-2/ └── ... ``` ## 开发 ### 运行测试 ``` # 测试 configuration 加载 ./gh_repo_cloner.sh --help # 测试身份验证检查 gh auth status # Dry run sanity checks ./gh_repo_cloner.sh --sanity-check # 测试 repository 过滤 ./gh_repo_cloner.sh --sanity-check non-existent-repo # Should show available repos ``` ## 最佳实践 ### 对于组织 - **定期审计**:每月运行一次完整性检查以确保仓库标准 - **标准化模板**:使用该脚本识别缺少 issue/PR 模板的仓库 - **安全合规**:确保所有仓库都有 `SECURITY.md` 文件 - **文档**:验证所有项目都有合适的 `README.md` 和 `docs/` 目录 - **针对性审查**:在代码审查期间使用仓库过滤来验证特定项目 ### 对于仓库管理 - **批量更新**:使用该脚本识别需要标准化的仓库 - **定期同步**:定期运行脚本以保持本地副本最新 - **干净的工作目录**:在运行更新之前,确保本地仓库没有未提交的更改 - **新人入职**:将完整性检查结果包含在新开发人员入职培训中 - **合规性**:跟踪全组织对仓库标准的遵守情况 - **针对性修复**:使用过滤来验证特定仓库上的修复 ## 局限性 - **大型组织**:对于拥有 1000+ 仓库的组织,建议分批运行 - **私有仓库访问**:需要适当的 GitHub 权限 - **存储空间**:克隆大量仓库需要大量的磁盘空间 - **网络使用**:初始克隆会消耗大量带宽 ## 故障排除 ### 常见问题 **"找不到组织" (Organization not found)** - 验证 `config.env` 中的组织名称 - 检查该组织是否存在且可访问 **"找不到仓库" (No repositories found)** - 组织可能只有私有仓库(使用 `gh auth login` 进行身份验证) - 组织名称可能不正确 **"找不到仓库 'repo-name'"**(过滤时) - 检查仓库名称的拼写 - 确保首先克隆了仓库(运行时不加 `-s` 标志) - 仓库可能是不同的大小写(名称区分大小写) - 使用错误输出查看可用的仓库 **"权限拒绝" (Permission denied)** - SSH 密钥未正确配置 - 使用 `gh auth login` 进行身份验证 - 检查仓库访问权限 **"超出速率限制" (Rate limit exceeded)** - 使用 GitHub CLI 认证:`gh auth login` - 等待速率限制重置(显示在错误消息中) **"更新仓库失败" (Failed to update repository)** - 仓库可能有未提交的本地更改 - 检查合并冲突:`cd repo_directory && git status` - 如果安全,重置本地更改:`git reset --hard origin/main` - 可能表明存在网络连接问题 **"LICENSE 显示警告 (⚠) 符号"** - LICENSE 文件包含模板占位符,如 `` 或 `` - 编辑 LICENSE 文件,将占位符替换为实际值 - 常见占位符:`` → 实际年份,`` → 你的姓名/组织名称 **"LICENSE 显示丢失 (✗) 但文件存在"** - LICENSE 文件可能具有意外的名称或扩展名 - 支持的名称:`LICENSE`, `LICENSE.txt`, `LICENSE.md`, `license`, `License`, `COPYING`, `COPYRIGHT` - 检查文件权限(必须可读) - 验证文件不是目录或符号链接 ## 许可证 本项目基于 MIT 许可证授权 - 详情请参阅 [LICENSE](LICENSE) 文件。 ## 支持 - **问题**:通过 [GitHub Issues](../../issues) 报告错误并请求功能- **讨论**:在 [GitHub Discussions](../../discussions) 中加入对话 - **文档**:查看此 README 和内联脚本注释 **用心制作,旨在为您提供更好的仓库管理体验**
标签:Bash, SOC Prime, 应用安全, 开发工具, 数字取证, 网络安全研究, 自动化脚本