Files
opencode/skill/gitea/repository-operations.md
Voson 5a05d5ab53 chore: 重构 OpenCode 命令和技能文档体系
- 新增:统一的 git 命令文档(add/commit/push/pull 等)
- 新增:整合的 Gitea 技能文档(API、运行器、工作流等)
- 新增:工作流模板(Android、Go、Node.js 等)
- 移除:已弃用的旧命令脚本和发布脚本
- 改进:.gitignore 添加敏感文件保护规则
- 改进:AGENTS.md 完善了开发规范和示例

此次重组统一了命令和技能的文档结构,便于后续维护和扩展。
2026-01-13 00:27:21 +08:00

14 KiB
Raw Permalink Blame History

Gitea 仓库操作

创建和管理 Gitea 仓库的完整指南。

概述

本文档介绍如何通过 Gitea API 创建和管理仓库,包括:

  • 创建组织/用户仓库
  • 初始化仓库结构
  • 配置 Actions 设置
  • 管理 Secrets 和 Variables
  • 设置 Webhooks

创建仓库

使用命令创建

快速创建(使用默认组织):

/gitea-create-repo my-project

指定 owner

/create-gitea-repo ai/my-project
/create-gitea-repo username/my-project

指定可见性

/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: 加载配置

config_file="$HOME/.config/gitea/config.env"

if [ ! -f "$config_file" ]; then
  echo "❌ Gitea 未配置,请运行 /gitea-reset"
  exit 1
fi

source "$config_file"

步骤 2: 解析输入

input="$1"

# 解析 owner/repo
if [[ "$input" =~ / ]]; then
  owner=$(echo "$input" | cut -d'/' -f1)
  repo=$(echo "$input" | cut -d'/' -f2)
else
  # 使用默认组织或当前用户
  if [ -z "$GITEA_DEFAULT_ORG" ]; then
    # 获取当前用户
    owner=$(curl -s -H "Authorization: token $GITEA_TOKEN" \
      "${GITEA_URL}/api/v1/user" | jq -r '.login')
    
    if [ -z "$owner" ] || [ "$owner" = "null" ]; then
      echo "❌ 无法获取当前用户信息,请使用 owner/repo 格式"
      exit 1
    fi
    
    echo "使用当前用户: $owner"
  else
    owner="$GITEA_DEFAULT_ORG"
    echo "使用默认组织: $owner"
  fi
  repo="$input"
fi

# 解析可见性
visibility="${2:-private}"
private_bool=$([ "$visibility" = "private" ] && echo "true" || echo "false")

步骤 3: 验证仓库名

# 仓库名只能包含字母、数字、下划线、连字符和点
if ! [[ "$repo" =~ ^[a-zA-Z0-9_.-]+$ ]]; then
  echo "❌ 仓库名只能包含字母、数字、下划线、连字符和点"
  exit 1
fi

步骤 4: 调用 API 创建

echo "正在创建仓库: $owner/$repo ($visibility)"

# 尝试组织仓库
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/orgs/${owner}/repos")

http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')

# 如果 404可能是用户而非组织
if [ "$http_code" = "404" ]; then
  echo "⚠️  组织不存在,尝试创建用户仓库..."
  
  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}
    }" \
    "${GITEA_URL}/api/v1/user/repos")
  
  http_code=$(echo "$response" | tail -n1)
  body=$(echo "$response" | sed '$d')
fi

# 处理响应
case "$http_code" in
  201)
    echo "✓ 仓库创建成功"
    ;;
  409)
    echo "❌ 仓库已存在"
    exit 1
    ;;
  *)
    echo "❌ 创建失败 (HTTP $http_code)"
    echo "$body" | jq -r '.message // empty'
    exit 1
    ;;
esac

步骤 5: 提取仓库信息

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 Remote

read -p "是否将此仓库添加为 Git remote? [Y/n] " add_remote

if [[ ! "$add_remote" =~ ^[Nn]$ ]]; then
  # 检查是否是 Git 仓库
  if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    echo "当前目录不是 Git 仓库"
    read -p "是否初始化 Git 仓库? [Y/n] " init_git
    
    if [[ ! "$init_git" =~ ^[Nn]$ ]]; then
      git init
      echo "✓ Git 仓库已初始化"
    else
      exit 0
    fi
  fi
  
  # 检查 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 已更新"
    fi
  else
    git remote add origin "$clone_url"
    echo "✓ origin remote 已添加"
  fi
  
  # 显示 remote 信息
  echo ""
  echo "当前 remote:"
  git remote -v
fi

仓库初始化

初始化基本结构

创建常见的仓库文件:

# 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

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 用于非敏感配置:

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

#!/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

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

curl -s -H "Authorization: token $GITEA_TOKEN" \
  "$GITEA_URL/api/v1/repos/$owner/$repo/hooks" | jq .

删除 Webhook

hook_id=1

curl -X DELETE \
  -H "Authorization: token $GITEA_TOKEN" \
  "$GITEA_URL/api/v1/repos/$owner/$repo/hooks/$hook_id"

仓库设置

更新仓库信息

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"

启用/禁用功能

# 禁用 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"

协作者管理

添加协作者

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: 管理员

列出协作者

curl -s -H "Authorization: token $GITEA_TOKEN" \
  "$GITEA_URL/api/v1/repos/$owner/$repo/collaborators" | jq .

移除协作者

username="collaborator"

curl -X DELETE \
  -H "Authorization: token $GITEA_TOKEN" \
  "$GITEA_URL/api/v1/repos/$owner/$repo/collaborators/$username"

常见操作

检查仓库是否存在

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

归档仓库

curl -X POST \
  -H "Authorization: token $GITEA_TOKEN" \
  "$GITEA_URL/api/v1/repos/$owner/$repo/archive"

echo "✓ 仓库已归档"

删除仓库

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

批量操作

批量创建仓库

#!/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

#!/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 - 仓库已存在

解决:

# 列出所有仓库
curl -s -H "Authorization: token $GITEA_TOKEN" \
  "$GITEA_URL/api/v1/orgs/$org/repos" | jq -r '.[].name'

Secret 配置失败

症状: HTTP 404 - 仓库不存在

解决:

# 检查仓库是否存在
curl -s -H "Authorization: token $GITEA_TOKEN" \
  "$GITEA_URL/api/v1/repos/$owner/$repo"

权限不足

症状: HTTP 403 - Forbidden

解决:

  • 检查 Token 是否有 repo 权限
  • 检查是否是仓库/组织的成员
  • 使用管理员账户

相关资源

版本

  • 文档版本: 1.0
  • 最后更新: 2026-01-12