# Gitea 仓库操作 创建和管理 Gitea 仓库的完整指南。 ## 概述 本文档介绍如何通过 Gitea API 创建和管理仓库,包括: - 创建组织/用户仓库 - 初始化仓库结构 - 配置 Actions 设置 - 管理 Secrets 和 Variables - 设置 Webhooks ## 快速使用 ### 核心原则(简洁高效) 1. **智能解析**:自动识别 `组织/仓库` 格式,优先使用指定组织而非默认组织 2. **默认私有**:除非明确指定,所有仓库默认创建为私有 3. **简化验证**:默认假设组织存在,API创建失败时清晰提示解决方案 4. **Git集成**:自动检查Git仓库状态,提供一键初始化、提交、推送完整流程 5. **错误处理**:API失败时给出具体操作建议,而非预先复杂验证 ### 常用命令(简洁高效) ```bash # 智能解析组织/仓库格式(默认私有) /gitea-create-repo shigongcao/shigongcao # 使用默认组织创建公开仓库 /gitea-create-repo my-project public # 自动检查Git状态,提供完整初始化流程 /gitea-create-repo org/project # 特性说明: # 1. 自动识别组织/仓库格式 # 2. 默认创建私有仓库(除非指定public) # 3. 自动检查当前目录Git状态 # 4. 提供一键初始化、提交、推送选项 # 5. API失败时给出清晰解决方案(如组织不存在) ``` ## 创建仓库 ### 使用命令创建 **快速创建**(使用默认组织): ```bash /gitea-create-repo my-project ``` **指定 owner**: ```bash /create-gitea-repo ai/my-project /create-gitea-repo username/my-project ``` **指定可见性**: ```bash /create-gitea-repo ai/my-project public /create-gitea-repo ai/my-project private ``` ### 使用自然语言 ``` 用户: 创建一个新的 gitea 仓库,名为 my-project 用户: 在 ai 组织下创建仓库 test-repo 用户: 创建公开仓库 open-source-project ``` AI 会自动: 1. 加载 Gitea 配置 2. 解析仓库名称和 owner 3. 调用 API 创建仓库 4. 提示是否添加为 Git remote 5. 显示仓库信息(URLs 等) ### 创建流程详解 #### 步骤 1: 加载配置 ```bash config_file="$HOME/.config/gitea/config.env" if [ ! -f "$config_file" ]; then echo "❌ Gitea 未配置,请运行 /gitea-reset" exit 1 fi source "$config_file" ``` #### 步骤 2: 智能解析输入(简洁高效版) ```bash input="$1" # 智能解析:优先使用用户指定的组织 if [[ "$input" =~ / ]]; then owner=$(echo "$input" | cut -d'/' -f1) repo=$(echo "$input" | cut -d'/' -f2) echo "使用指定组织: $owner" echo "提示:假设组织存在,如不存在会在API创建时提示" else # 未指定组织,使用默认组织或当前用户 if [ -z "$GITEA_DEFAULT_ORG" ]; then # 获取当前用户 echo "未指定组织,获取当前用户..." owner=$(curl -s -H "Authorization: token $GITEA_TOKEN" \ "${GITEA_URL}/api/v1/user" | jq -r '.login') if [ -z "$owner" ] || [ "$owner" = "null" ]; then echo "❌ 无法获取当前用户信息,请使用 组织/仓库 格式" echo "例如:/gitea-create-repo shigongcao/shigongcao" exit 1 fi echo "使用当前用户: $owner" else owner="$GITEA_DEFAULT_ORG" echo "使用默认组织: $owner" fi repo="$input" fi # 解析可见性:默认私有仓库(除非明确指定公开) visibility="${2:-private}" if [[ "$visibility" != "private" && "$visibility" != "public" ]]; then echo "⚠️ 可见性参数无效,使用默认值: private" visibility="private" fi private_bool=$([ "$visibility" = "private" ] && echo "true" || echo "false") echo "仓库可见性: $visibility" # 提前检查当前目录是否是 Git 仓库(为后续步骤做准备) if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then echo "⚠️ 当前目录不是 Git 仓库" echo "提示:创建远程仓库后可以初始化本地 Git 仓库并推送代码" fi ``` #### 步骤 3: 验证仓库名 ```bash # 仓库名只能包含字母、数字、下划线、连字符和点 if ! [[ "$repo" =~ ^[a-zA-Z0-9_.-]+$ ]]; then echo "❌ 仓库名只能包含字母、数字、下划线、连字符和点" exit 1 fi ``` #### 步骤 4: 调用 API 创建(带详细错误处理) ```bash echo "正在创建仓库: $owner/$repo ($visibility)" # 检查 Token 权限 echo "检查 Token 权限..." user_info=$(curl -s -H "Authorization: token $GITEA_TOKEN" "${GITEA_URL}/api/v1/user") username=$(echo "$user_info" | jq -r '.login // empty') if [ -z "$username" ] || [ "$username" = "null" ]; then echo "❌ Token 无效或权限不足" echo "请检查:" echo "1. Token 是否有效" echo "2. Token 是否有 'repo' 权限" echo "3. GITEA_URL 是否正确" exit 1 fi echo "✓ Token 有效,当前用户: $username" # 尝试创建组织仓库 echo "调用 Gitea API 创建仓库..." response=$(curl -s -w "\n%{http_code}" -X POST \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"name\": \"${repo}\", \"private\": ${private_bool}, \"auto_init\": false, \"default_branch\": \"main\", \"description\": \"\" }" \ "${GITEA_URL}/api/v1/orgs/${owner}/repos") http_code=$(echo "$response" | tail -n1) body=$(echo "$response" | sed '$d') # 处理响应 case "$http_code" in 201) echo "✓ 仓库创建成功" ;; 400) error_msg=$(echo "$body" | jq -r '.message // "未知错误"') echo "❌ 请求参数错误: $error_msg" echo "请检查:" echo "1. 仓库名格式是否正确" echo "2. 是否缺少必要参数" exit 1 ;; 403) echo "❌ 权限不足" echo "请检查:" echo "1. 是否有在组织 '$owner' 下创建仓库的权限" echo "2. 是否是组织成员" echo "3. Token 权限是否足够" exit 1 ;; 404) # 组织不存在(API 返回 404) echo "❌ API 创建失败:组织 '$owner' 不存在" # 检查是否为当前用户(可能用户输入的是自己的用户名) if [ "$owner" = "$username" ]; then echo "检测到 '$owner' 是当前用户,创建个人仓库..." response=$(curl -s -w "\n%{http_code}" -X POST \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"name\": \"${repo}\", \"private\": ${private_bool}, \"auto_init\": false, \"default_branch\": \"main\" }" \ "${GITEA_URL}/api/v1/user/repos") http_code=$(echo "$response" | tail -n1) body=$(echo "$response" | sed '$d') if [ "$http_code" = "201" ]; then echo "✓ 个人仓库创建成功" else error_msg=$(echo "$body" | jq -r '.message // "未知错误"') echo "❌ 个人仓库创建失败 (HTTP $http_code): $error_msg" exit 1 fi else echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "组织不存在,请先创建组织" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" echo "您可以通过以下方式创建组织 '$owner':" echo "1. 访问 ${GITEA_URL}/org/create" echo "2. 使用 Gitea Web 界面创建组织" echo "3. 或者使用个人仓库格式: $username/$repo" echo "" echo "创建组织后,重新运行此命令创建仓库。" exit 1 fi ;; 409) echo "❌ 仓库已存在: $owner/$repo" echo "请使用不同的仓库名或删除现有仓库" exit 1 ;; *) error_msg=$(echo "$body" | jq -r '.message // "未知错误"') echo "❌ 创建失败 (HTTP $http_code): $error_msg" exit 1 ;; esac ``` #### 步骤 5: 提取仓库信息 ```bash html_url=$(echo "$body" | jq -r '.html_url') clone_url=$(echo "$body" | jq -r '.clone_url') ssh_url=$(echo "$body" | jq -r '.ssh_url') echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "仓库信息" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" echo " 名称: $owner/$repo" echo " 可见性: $visibility" echo " Web URL: $html_url" echo " HTTPS URL: $clone_url" echo " SSH URL: $ssh_url" echo "" ``` #### 步骤 6: Git 仓库集成(简洁高效版) ```bash echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "Git 仓库集成" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" # 检查是否是 Git 仓库 if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then echo "当前目录不是 Git 仓库" read -p "是否初始化 Git 仓库并添加 remote? [Y/n] " init_git if [[ "$init_git" =~ ^[Nn]$ ]]; then echo "跳过 Git 初始化,仅创建远程仓库。" echo "您可以在需要时手动执行:" echo " git init" echo " git remote add origin \"$clone_url\"" exit 0 fi # 初始化 Git 仓库 echo "正在初始化 Git 仓库..." git init echo "✓ Git 仓库已初始化" # 检查 origin 是否已存在 if git remote get-url origin >/dev/null 2>&1; then existing_url=$(git remote get-url origin) echo "⚠️ origin remote 已存在: $existing_url" read -p "是否覆盖为新的仓库? [y/N] " overwrite if [[ "$overwrite" =~ ^[Yy]$ ]]; then git remote set-url origin "$clone_url" echo "✓ origin remote 已更新为: $clone_url" else echo "保持现有的 origin remote" fi else git remote add origin "$clone_url" echo "✓ origin remote 已添加: $clone_url" fi # 可选:添加文件、提交并推送 echo "" read -p "是否添加当前文件、提交并推送到远程仓库? [Y/n] " push_code if [[ ! "$push_code" =~ ^[Nn]$ ]]; then echo "添加所有文件到暂存区..." git add . echo "创建初始提交..." git commit -m "Initial commit" || { echo "⚠️ 提交失败(可能没有文件可提交)" echo "请手动添加文件后提交" } echo "推送到远程仓库 (main 分支)..." git branch -M main 2>/dev/null git push -u origin main echo "✓ 代码已推送到远程仓库" else echo "跳过推送,您可以在需要时手动推送代码。" fi else # 已经是 Git 仓库,询问是否添加/更新 remote echo "当前目录已是 Git 仓库" read -p "是否添加/更新 origin remote 为此仓库? [Y/n] " add_remote if [[ ! "$add_remote" =~ ^[Nn]$ ]]; then # 检查 origin 是否已存在 if git remote get-url origin >/dev/null 2>&1; then existing_url=$(git remote get-url origin) echo "⚠️ origin remote 已存在: $existing_url" read -p "是否覆盖? [y/N] " overwrite if [[ "$overwrite" =~ ^[Yy]$ ]]; then git remote set-url origin "$clone_url" echo "✓ origin remote 已更新" else echo "保持现有的 origin remote" fi else git remote add origin "$clone_url" echo "✓ origin remote 已添加" fi fi fi # 显示当前状态 echo "" echo "当前 Git 状态:" git status --short 2>/dev/null || echo "(非 Git 仓库)" echo "" echo "Remote 配置:" git remote -v 2>/dev/null || echo "(无 remote 配置)" ``` ## 仓库初始化 ### 初始化基本结构 创建常见的仓库文件: ```bash # README.md cat > README.md << 'EOF' # Project Name 项目描述 ## 功能特性 - 特性 1 - 特性 2 ## 快速开始 ```bash # 安装依赖 make install # 运行项目 make run ``` ## 许可证 MIT License EOF # .gitignore cat > .gitignore << 'EOF' # OS .DS_Store Thumbs.db # IDE .vscode/ .idea/ *.swp *.swo # Dependencies node_modules/ vendor/ # Build dist/ build/ *.exe *.dll *.so *.dylib # Logs *.log logs/ # Environment .env .env.local EOF # LICENSE cat > LICENSE << 'EOF' MIT License Copyright (c) 2026 Permission is hereby granted... EOF git add README.md .gitignore LICENSE git commit -m "Initial commit: Add basic project files" ``` ### 创建分支保护规则 ```bash # 通过 API 设置分支保护(需要管理员权限) curl -X POST \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "enable_push": false, "enable_push_whitelist": true, "push_whitelist_usernames": ["admin"], "require_signed_commits": false, "enable_status_check": true, "status_check_contexts": ["continuous-integration/gitea"] }' \ "$GITEA_URL/api/v1/repos/$owner/$repo/branch_protections" ``` ## Actions 配置 ### 启用 Actions Actions 在 Gitea 1.19+ 中默认启用,无需额外配置。 ### 配置 Secrets **方法 1: 通过 UI** 1. 打开仓库 → Settings → Secrets → Actions 2. 点击 "New Secret" 3. 输入 Name 和 Value 4. 保存 **方法 2: 通过 API** ```bash source ~/.config/gitea/config.env owner="ai" repo="my-project" secret_name="DEPLOY_KEY" secret_value="super-secret-key" # Base64 编码 encoded=$(echo -n "$secret_value" | base64) # 创建 Secret curl -X PUT \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"data\":\"${encoded}\"}" \ "$GITEA_URL/api/v1/repos/$owner/$repo/actions/secrets/$secret_name" echo "✓ Secret $secret_name 已创建" ``` ### 配置 Variables Variables 用于非敏感配置: ```bash owner="ai" repo="my-project" var_name="ENVIRONMENT" var_value="production" # 创建 Variable curl -X POST \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"value\":\"${var_value}\"}" \ "$GITEA_URL/api/v1/repos/$owner/$repo/actions/variables/$var_name" echo "✓ Variable $var_name 已创建" ``` ### 批量配置 Secrets ```bash #!/bin/bash source ~/.config/gitea/config.env owner="ai" repo="my-project" # Secret 列表 declare -A secrets=( ["REGISTRY_PASSWORD"]="docker-password" ["API_TOKEN"]="api-token-value" ["DEPLOY_KEY"]="ssh-private-key" ) for name in "${!secrets[@]}"; do value="${secrets[$name]}" encoded=$(echo -n "$value" | base64) curl -s -X PUT \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"data\":\"${encoded}\"}" \ "$GITEA_URL/api/v1/repos/$owner/$repo/actions/secrets/$name" echo "✓ $name" done ``` ## Webhook 配置 ### 创建 Webhook ```bash source ~/.config/gitea/config.env owner="ai" repo="my-project" webhook_url="https://example.com/webhook" webhook_secret="webhook-secret-key" curl -X POST \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"type\": \"gitea\", \"config\": { \"url\": \"${webhook_url}\", \"content_type\": \"json\", \"secret\": \"${webhook_secret}\" }, \"events\": [\"push\", \"pull_request\", \"release\"], \"active\": true }" \ "$GITEA_URL/api/v1/repos/$owner/$repo/hooks" echo "✓ Webhook 已创建" ``` ### 常用事件类型 | 事件 | 说明 | |------|------| | `push` | 代码推送 | | `pull_request` | PR 创建/更新 | | `issues` | Issue 创建/更新 | | `release` | Release 发布 | | `create` | 分支/标签创建 | | `delete` | 分支/标签删除 | ### 列出 Webhooks ```bash curl -s -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_URL/api/v1/repos/$owner/$repo/hooks" | jq . ``` ### 删除 Webhook ```bash hook_id=1 curl -X DELETE \ -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_URL/api/v1/repos/$owner/$repo/hooks/$hook_id" ``` ## 仓库设置 ### 更新仓库信息 ```bash curl -X PATCH \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "description": "新的仓库描述", "website": "https://example.com", "private": false, "has_issues": true, "has_wiki": false, "default_branch": "main" }' \ "$GITEA_URL/api/v1/repos/$owner/$repo" ``` ### 启用/禁用功能 ```bash # 禁用 Wiki curl -X PATCH \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"has_wiki": false}' \ "$GITEA_URL/api/v1/repos/$owner/$repo" # 启用 Issues curl -X PATCH \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"has_issues": true}' \ "$GITEA_URL/api/v1/repos/$owner/$repo" ``` ## 协作者管理 ### 添加协作者 ```bash username="collaborator" curl -X PUT \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"permission": "write"}' \ "$GITEA_URL/api/v1/repos/$owner/$repo/collaborators/$username" echo "✓ 已添加协作者: $username" ``` **权限级别**: - `read`: 只读 - `write`: 读写 - `admin`: 管理员 ### 列出协作者 ```bash curl -s -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_URL/api/v1/repos/$owner/$repo/collaborators" | jq . ``` ### 移除协作者 ```bash username="collaborator" curl -X DELETE \ -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_URL/api/v1/repos/$owner/$repo/collaborators/$username" ``` ## 常见操作 ### 检查仓库是否存在 ```bash repo_exists() { local owner="$1" local repo="$2" response=$(curl -s -w "\n%{http_code}" \ -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_URL/api/v1/repos/$owner/$repo") http_code=$(echo "$response" | tail -n1) [ "$http_code" = "200" ] } if repo_exists "ai" "my-project"; then echo "仓库存在" else echo "仓库不存在" fi ``` ### 归档仓库 ```bash curl -X POST \ -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_URL/api/v1/repos/$owner/$repo/archive" echo "✓ 仓库已归档" ``` ### 删除仓库 ```bash echo "⚠️ 警告: 此操作无法撤销!" read -p "确认删除仓库 $owner/$repo? 输入 'yes' 确认: " confirm if [ "$confirm" = "yes" ]; then curl -X DELETE \ -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_URL/api/v1/repos/$owner/$repo" echo "✓ 仓库已删除" else echo "已取消" fi ``` ## 批量操作 ### 批量创建仓库 ```bash #!/bin/bash source ~/.config/gitea/config.env org="ai" repos=("project-a" "project-b" "project-c") for repo in "${repos[@]}"; do echo "创建仓库: $repo" curl -s -X POST \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"name\": \"${repo}\", \"private\": true, \"auto_init\": true }" \ "$GITEA_URL/api/v1/orgs/$org/repos" | jq -r '.html_url' sleep 1 # 避免请求过快 done ``` ### 批量配置 Secrets ```bash #!/bin/bash source ~/.config/gitea/config.env org="ai" repos=("repo1" "repo2" "repo3") secret_name="DEPLOY_KEY" secret_value="shared-secret" encoded=$(echo -n "$secret_value" | base64) for repo in "${repos[@]}"; do echo "配置 $repo..." curl -s -X PUT \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"data\":\"${encoded}\"}" \ "$GITEA_URL/api/v1/repos/$org/$repo/actions/secrets/$secret_name" echo "✓ $repo" done ``` ## 故障排查 ### 仓库创建失败 **症状**: HTTP 409 - 仓库已存在 **解决**: ```bash # 列出所有仓库 curl -s -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_URL/api/v1/orgs/$org/repos" | jq -r '.[].name' ``` ### Secret 配置失败 **症状**: HTTP 404 - 仓库不存在 **解决**: ```bash # 检查仓库是否存在 curl -s -H "Authorization: token $GITEA_TOKEN" \ "$GITEA_URL/api/v1/repos/$owner/$repo" ``` ### 权限不足 **症状**: HTTP 403 - Forbidden **解决**: - 检查 Token 是否有 `repo` 权限 - 检查是否是仓库/组织的成员 - 使用管理员账户 ## 相关资源 - [Gitea API 文档](https://docs.gitea.com/api/1.20/) - [API 参考](./api-reference.md) - [环境配置](./setup-guide.md) - [Workflow 生成器](./workflow-generator.md) ## 版本 - **文档版本**: 1.1 - **最后更新**: 2026-01-23 - **主要改进**: - 智能解析输入:优先使用指定组织而非默认组织 - 组织存在性验证和清晰错误提示 - 默认私有仓库策略(除非明确指定公开) - 增强的错误处理:Token验证、权限检查、详细错误消息 - 完整的Git集成流程:可选自动初始化和推送