diff --git a/README.md b/README.md index 7f2536a..e137990 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ The official [GitLink](https://www.gitlink.org.cn) CLI tool — built for humans | 🔀 PR | Create, merge, review pull requests, view changed files | | 🌿 Branch | Create, delete, list, protect, unprotect branches | | 🏷️ Release | Create, view, delete releases | +| 🔗 Webhook | Create, view, update, delete, test webhooks, configure automation triggers | | 🏢 Org | Manage organizations, members, teams | | 🔧 CI | View builds, logs, CI/CD operations | | 🔍 Search | Search repositories, users | @@ -210,6 +211,34 @@ gitlink-cli branch +protect --name main gitlink-cli branch +unprotect --name main ``` +### Webhook Management + +```bash +# List all webhooks +gitlink-cli webhook +list --owner Gitlink --repo forgeplus + +# Create a webhook +gitlink-cli webhook +create --owner Gitlink --repo forgeplus --url https://ci.example.com/webhook --events push,pull_request + +# Create webhook with secret +gitlink-cli webhook +create --url https://jenkins.example.com/webhook --secret my-secret-key --events push --description "CI/CD trigger" + +# View webhook details +gitlink-cli webhook +info --id 456 + +# Update webhook +gitlink-cli webhook +update --id 456 --url https://new-url.example.com/webhook --events push,pull_request,issue + +# Test webhook +gitlink-cli webhook +test --id 456 + +# Delete webhook +gitlink-cli webhook +delete --id 456 + +# List supported event types +gitlink-cli webhook +events +``` + ### Release Management ```bash diff --git a/README.zh-CN.md b/README.zh-CN.md index a301ac0..0eb0fcd 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -32,6 +32,7 @@ | 🔀 PR | 创建、合并、Review Pull Request,查看变更文件 | | 🌿 分支 | 创建、删除、保护分支 | | 🏷️ 发布 | 创建、查看、删除 Release | +| 🔗 Webhook | 创建、查看、更新、删除、测试 Webhook,配置自动化触发器 | | 🏢 组织 | 管理组织、成员、团队 | | 🔧 CI | 查看构建、日志、CI/CD 操作 | | 🔍 搜索 | 搜索仓库、用户 | @@ -228,6 +229,34 @@ gitlink-cli pr +merge --owner Gitlink --repo forgeplus -i 42 gitlink-cli pr +files --owner Gitlink --repo forgeplus -i 42 ``` +### Webhook 管理 + +```bash +# 列出所有 Webhook +gitlink-cli webhook +list --owner Gitlink --repo forgeplus + +# 创建 Webhook +gitlink-cli webhook +create --owner Gitlink --repo forgeplus --url https://ci.example.com/webhook --events push,pull_request + +# 创建带密钥的 Webhook +gitlink-cli webhook +create --url https://jenkins.example.com/webhook --secret my-secret-key --events push --description "CI/CD trigger" + +# 查看 Webhook 详情 +gitlink-cli webhook +info --id 456 + +# 更新 Webhook +gitlink-cli webhook +update --id 456 --url https://new-url.example.com/webhook --events push,pull_request,issue + +# 测试 Webhook +gitlink-cli webhook +test --id 456 + +# 删除 Webhook +gitlink-cli webhook +delete --id 456 + +# 查看支持的事件类型 +gitlink-cli webhook +events +``` + ### 发布管理 ```bash diff --git a/shortcuts/register.go b/shortcuts/register.go index d511219..9e8727f 100644 --- a/shortcuts/register.go +++ b/shortcuts/register.go @@ -13,6 +13,7 @@ import ( "github.com/gitlink-org/gitlink-cli/shortcuts/repo" "github.com/gitlink-org/gitlink-cli/shortcuts/search" "github.com/gitlink-org/gitlink-cli/shortcuts/user" + "github.com/gitlink-org/gitlink-cli/shortcuts/webhook" // 新增webhook管理 "github.com/gitlink-org/gitlink-cli/shortcuts/wiki" // 新增wiki管理 ) @@ -28,7 +29,8 @@ func RegisterAll(root *cobra.Command) { "user": user.Shortcuts(), "search": search.Shortcuts(), "ci": ci.Shortcuts(), - "wiki": wiki.Shortcuts(), // 新增wiki + "wiki": wiki.Shortcuts(), // 新增wiki + "webhook": webhook.Shortcuts(), // 新增webhook } descriptions := map[string]string{ @@ -41,7 +43,8 @@ func RegisterAll(root *cobra.Command) { "user": "User operations", "search": "Search operations", "ci": "CI/CD operations", - "wiki": "Wiki operations", // 新增wiki + "wiki": "Wiki operations", // 新增wiki + "webhook": "Webhook operations", // 新增webhook } for name, shortcuts := range groups { diff --git a/shortcuts/webhook/webhook.go b/shortcuts/webhook/webhook.go new file mode 100644 index 0000000..5bd1acb --- /dev/null +++ b/shortcuts/webhook/webhook.go @@ -0,0 +1,310 @@ +package webhook + +import ( + "fmt" + "net/url" + "strings" + + "github.com/gitlink-org/gitlink-cli/internal/output" + "github.com/gitlink-org/gitlink-cli/shortcuts/common" +) + +// 支持的Webhook事件类型 +var supportedEvents = []string{ + "push", + "pull_request", + "issue", + "issue_assign", + "issue_comment", + "pull_request_assign", + "pull_request_comment", + "merge_request", + "repository", + "branch", + "tag", +} + +func isEventSupported(event string) bool { + for _, supported := range supportedEvents { + if event == supported { + return true + } + } + return false +} + +func parseEvents(eventsStr string) []string { + if eventsStr == "" { + return []string{"push"} // 默认事件 + } + events := strings.Split(eventsStr, ",") + var validEvents []string + for _, event := range events { + event = strings.TrimSpace(event) + if isEventSupported(event) { + validEvents = append(validEvents, event) + } + } + return validEvents +} + +func Shortcuts() []*common.Shortcut { + return []*common.Shortcut{ + { + Name: "list", + Description: "List all webhooks for a repository", + Flags: []common.Flag{ + {Name: "page", Short: "p", Usage: "Page number", Default: "1"}, + {Name: "limit", Short: "l", Usage: "Items per page", Default: "20"}, + }, + Run: func(ctx *common.RuntimeContext) error { + if err := ctx.ResolveOwnerRepo(); err != nil { + return err + } + q := url.Values{} + q.Set("page", ctx.Arg("page")) + q.Set("limit", ctx.Arg("limit")) + env, err := ctx.CallAPIWithQuery("GET", ctx.RepoPath()+"/hooks", q) + if err != nil { + return err + } + return ctx.Output(env) + }, + }, + { + Name: "create", + Description: "Create a new webhook", + Flags: []common.Flag{ + {Name: "url", Short: "u", Usage: "Webhook callback URL", Required: true}, + {Name: "events", Short: "e", Usage: "Trigger events (comma-separated), e.g., push,pull_request,issue", Default: "push"}, + {Name: "active", Usage: "Webhook active status (true/false)", Default: "true"}, + {Name: "content_type", Usage: "Content type (json/form)", Default: "json"}, + {Name: "secret", Usage: "Webhook secret for HMAC verification"}, + {Name: "description", Short: "d", Usage: "Webhook description"}, + }, + Run: func(ctx *common.RuntimeContext) error { + if err := ctx.ResolveOwnerRepo(); err != nil { + return err + } + + webhookURL, err := ctx.RequireArg("url") + if err != nil { + return err + } + + events := parseEvents(ctx.Arg("events")) + if len(events) == 0 { + return fmt.Errorf("no valid events specified. Supported events: %s", strings.Join(supportedEvents, ", ")) + } + + payload := map[string]interface{}{ + "hook_url": webhookURL, + "events": events, + "is_active": ctx.Arg("active") == "true", + "content_type": ctx.Arg("content_type"), + } + + if secret := ctx.Arg("secret"); secret != "" { + payload["secret"] = secret + } + + if description := ctx.Arg("description"); description != "" { + payload["description"] = description + } + + env, err := ctx.CallAPI("POST", ctx.RepoPath()+"/hooks", payload) + if err != nil { + return err + } + return ctx.Output(env) + }, + }, + { + Name: "update", + Description: "Update an existing webhook", + Flags: []common.Flag{ + {Name: "id", Short: "i", Usage: "Webhook ID", Required: true}, + {Name: "url", Short: "u", Usage: "Webhook callback URL"}, + {Name: "events", Short: "e", Usage: "Trigger events (comma-separated)"}, + {Name: "active", Usage: "Webhook active status (true/false)"}, + {Name: "content_type", Usage: "Content type (json/form)"}, + {Name: "secret", Usage: "Webhook secret for HMAC verification"}, + {Name: "description", Short: "d", Usage: "Webhook description"}, + }, + Run: func(ctx *common.RuntimeContext) error { + if err := ctx.ResolveOwnerRepo(); err != nil { + return err + } + + webhookID, err := ctx.RequireArg("id") + if err != nil { + return err + } + + payload := map[string]interface{}{} + + if webhookURL := ctx.Arg("url"); webhookURL != "" { + payload["hook_url"] = webhookURL + } + + if events := ctx.Arg("events"); events != "" { + validEvents := parseEvents(events) + if len(validEvents) == 0 { + return fmt.Errorf("no valid events specified. Supported events: %s", strings.Join(supportedEvents, ", ")) + } + payload["events"] = validEvents + } + + if active := ctx.Arg("active"); active != "" { + payload["is_active"] = active == "true" + } + + if contentType := ctx.Arg("content_type"); contentType != "" { + payload["content_type"] = contentType + } + + if secret := ctx.Arg("secret"); secret != "" { + payload["secret"] = secret + } + + if description := ctx.Arg("description"); description != "" { + payload["description"] = description + } + + if len(payload) == 0 { + return fmt.Errorf("no fields specified for update") + } + + env, err := ctx.CallAPI("PUT", fmt.Sprintf("%s/hooks/%s", ctx.RepoPath(), webhookID), payload) + if err != nil { + return err + } + return ctx.Output(env) + }, + }, + { + Name: "delete", + Description: "Delete a webhook", + Flags: []common.Flag{ + {Name: "id", Short: "i", Usage: "Webhook ID", Required: true}, + }, + Run: func(ctx *common.RuntimeContext) error { + if err := ctx.ResolveOwnerRepo(); err != nil { + return err + } + + webhookID, err := ctx.RequireArg("id") + if err != nil { + return err + } + + _, delErr := ctx.CallAPI("DELETE", fmt.Sprintf("%s/hooks/%s", ctx.RepoPath(), webhookID), nil) + if delErr != nil { + // 验证是否真的删除成功(类似release的处理) + _, viewErr := ctx.CallAPI("GET", fmt.Sprintf("%s/hooks/%s", ctx.RepoPath(), webhookID), nil) + if viewErr != nil { + // Webhook不存在了,说明删除成功 + return ctx.Output(output.SuccessEnvelope(map[string]interface{}{ + "message": "Webhook deleted successfully", + }, nil)) + } + return delErr + } + return ctx.Output(output.SuccessEnvelope(map[string]interface{}{ + "message": "Webhook deleted successfully", + }, nil)) + }, + }, + { + Name: "test", + Description: "Test a webhook delivery (send a ping event)", + Flags: []common.Flag{ + {Name: "id", Short: "i", Usage: "Webhook ID", Required: true}, + {Name: "event", Short: "e", Usage: "Event type to test (default: push)", Default: "push"}, + }, + Run: func(ctx *common.RuntimeContext) error { + if err := ctx.ResolveOwnerRepo(); err != nil { + return err + } + + webhookID, err := ctx.RequireArg("id") + if err != nil { + return err + } + + eventType := ctx.Arg("event") + if !isEventSupported(eventType) { + return fmt.Errorf("unsupported event type: %s. Supported events: %s", eventType, strings.Join(supportedEvents, ", ")) + } + + payload := map[string]interface{}{ + "event_type": eventType, + } + + env, err := ctx.CallAPI("POST", fmt.Sprintf("%s/hooks/%s/test", ctx.RepoPath(), webhookID), payload) + if err != nil { + return err + } + return ctx.Output(env) + }, + }, + { + Name: "info", + Description: "Show webhook details", + Flags: []common.Flag{ + {Name: "id", Short: "i", Usage: "Webhook ID", Required: true}, + }, + Run: func(ctx *common.RuntimeContext) error { + if err := ctx.ResolveOwnerRepo(); err != nil { + return err + } + + webhookID, err := ctx.RequireArg("id") + if err != nil { + return err + } + + env, err := ctx.CallAPI("GET", fmt.Sprintf("%s/hooks/%s", ctx.RepoPath(), webhookID), nil) + if err != nil { + return err + } + return ctx.Output(env) + }, + }, + { + Name: "events", + Description: "List all supported event types for webhooks", + Run: func(ctx *common.RuntimeContext) error { + eventInfo := make([]map[string]interface{}, 0) + for _, event := range supportedEvents { + eventInfo = append(eventInfo, map[string]interface{}{ + "event": event, + "supported": true, + "description": getEventDescription(event), + }) + } + return ctx.Output(output.SuccessEnvelope(eventInfo, nil)) + }, + }, + } +} + +func getEventDescription(event string) string { + descriptions := map[string]string{ + "push": "Code push events", + "pull_request": "Pull request events", + "issue": "Issue events", + "issue_assign": "Issue assignment events", + "issue_comment": "Issue comment events", + "pull_request_assign": "Pull request assignment events", + "pull_request_comment":"Pull request comment events", + "merge_request": "Merge request events", + "repository": "Repository events", + "branch": "Branch creation/deletion events", + "tag": "Tag creation/deletion events", + } + if desc, ok := descriptions[event]; ok { + return desc + } + return "Custom event" +} diff --git a/shortcuts/webhook/webhook_test.go b/shortcuts/webhook/webhook_test.go new file mode 100644 index 0000000..a2f6305 --- /dev/null +++ b/shortcuts/webhook/webhook_test.go @@ -0,0 +1,243 @@ +package webhook + +import ( + "strings" + "testing" + + "github.com/gitlink-org/gitlink-cli/shortcuts/common" +) + +func TestIsEventSupported(t *testing.T) { + tests := []struct { + name string + event string + expected bool + }{ + { + name: "supported event - push", + event: "push", + expected: true, + }, + { + name: "supported event - pull_request", + event: "pull_request", + expected: true, + }, + { + name: "supported event - issue", + event: "issue", + expected: true, + }, + { + name: "unsupported event", + event: "unsupported_event", + expected: false, + }, + { + name: "empty event", + event: "", + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := isEventSupported(tt.event) + if result != tt.expected { + t.Errorf("isEventSupported(%q) = %v, want %v", tt.event, result, tt.expected) + } + }) + } +} + +func TestParseEvents(t *testing.T) { + tests := []struct { + name string + events string + expected []string + }{ + { + name: "single event", + events: "push", + expected: []string{"push"}, + }, + { + name: "multiple events", + events: "push,pull_request,issue", + expected: []string{"push", "pull_request", "issue"}, + }, + { + name: "events with spaces", + events: "push, pull_request, issue", + expected: []string{"push", "pull_request", "issue"}, + }, + { + name: "mixed valid and invalid events", + events: "push,invalid_event,pull_request", + expected: []string{"push", "pull_request"}, + }, + { + name: "empty string - default to push", + events: "", + expected: []string{"push"}, + }, + { + name: "all invalid events", + events: "invalid1,invalid2", + expected: []string{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := parseEvents(tt.events) + if len(result) != len(tt.expected) { + t.Errorf("parseEvents(%q) returned %d events, want %d", tt.events, len(result), len(tt.expected)) + return + } + for i, event := range result { + if event != tt.expected[i] { + t.Errorf("parseEvents(%q)[%d] = %q, want %q", tt.events, i, event, tt.expected[i]) + } + } + }) + } +} + +func TestGetEventDescription(t *testing.T) { + tests := []struct { + name string + event string + expected string + }{ + { + name: "push event description", + event: "push", + expected: "Code push events", + }, + { + name: "pull_request event description", + event: "pull_request", + expected: "Pull request events", + }, + { + name: "issue event description", + event: "issue", + expected: "Issue events", + }, + { + name: "unknown event description", + event: "unknown_event", + expected: "Custom event", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := getEventDescription(tt.event) + if result != tt.expected { + t.Errorf("getEventDescription(%q) = %q, want %q", tt.event, result, tt.expected) + } + }) + } +} + +func TestShortcuts(t *testing.T) { + shortcuts := Shortcuts() + + if len(shortcuts) == 0 { + t.Fatal("Shortcuts() returned empty slice") + } + + // 验证所有必需的shortcuts都存在 + expectedShortcuts := []string{ + "list", "create", "update", "delete", "test", "info", "events", + } + + shortcutNames := make(map[string]bool) + for _, sc := range shortcuts { + shortcutNames[sc.Name] = true + } + + for _, expected := range expectedShortcuts { + if !shortcutNames[expected] { + t.Errorf("Missing shortcut: %s", expected) + } + } + + // 验证每个shortcut的基本属性 + for _, sc := range shortcuts { + if sc.Name == "" { + t.Error("Shortcut has empty Name") + } + if sc.Description == "" { + t.Errorf("Shortcut %q has empty Description", sc.Name) + } + if sc.Run == nil { + t.Errorf("Shortcut %q has nil Run function", sc.Name) + } + } +} + +// TestWebhookEventsList tests the events shortcut to ensure it returns valid event information +func TestWebhookEventsList(t *testing.T) { + shortcuts := Shortcuts() + var eventsShortcut *common.Shortcut + for _, sc := range shortcuts { + if sc.Name == "events" { + eventsShortcut = sc + break + } + } + + if eventsShortcut == nil { + t.Fatal("Events shortcut not found") + } + + // 验证所有支持的事件都有描述 + for _, event := range supportedEvents { + desc := getEventDescription(event) + if desc == "" { + t.Errorf("Event %q has empty description", event) + } + } +} + +// TestEventValidationIntegration tests event validation in an integrated manner +func TestEventValidationIntegration(t *testing.T) { + // 测试所有支持的事件都能被正确识别 + for _, event := range supportedEvents { + if !isEventSupported(event) { + t.Errorf("Supported event %q is not recognized by isEventSupported", event) + } + // 确保描述不为空 + desc := getEventDescription(event) + if desc == "" { + t.Errorf("Event %q has empty description", event) + } + } + + // 测试解析包含所有支持的事件字符串 + allEvents := strings.Join(supportedEvents, ",") + parsed := parseEvents(allEvents) + if len(parsed) != len(supportedEvents) { + t.Errorf("Parsing all events returned %d results, expected %d", len(parsed), len(supportedEvents)) + } +} + +// BenchmarkParseEvents benchmarks the event parsing function +func BenchmarkParseEvents(b *testing.B) { + eventsStr := "push,pull_request,issue,issue_assign,issue_comment,pull_request_assign,pull_request_comment" + for i := 0; i < b.N; i++ { + parseEvents(eventsStr) + } +} + +// BenchmarkIsEventSupported benchmarks the event validation function +func BenchmarkIsEventSupported(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, event := range supportedEvents { + isEventSupported(event) + } + } +} diff --git a/skills/gitlink-branch/references/branch-create.md b/skills/gitlink-branch/references/branch-create.md new file mode 100644 index 0000000..dbf935f --- /dev/null +++ b/skills/gitlink-branch/references/branch-create.md @@ -0,0 +1,100 @@ +# branch +create + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +从现有分支或 commit 创建新分支。 + +## 命令 + +```bash +# 从 master 创建分支 +gitlink-cli branch +create --name feature/new-feature + +# 从指定分支创建 +gitlink-cli branch +create --name hotfix/bug-123 --from develop + +# 从指定 commit 创建 +gitlink-cli branch +create --name feature/x --from abc123def + +# 指定仓库创建分支 +gitlink-cli branch +create --name feature/x --owner someone --repo myrepo +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--name, -n` | **是** | 新分支名称 | +| `--from, -f` | 否 | 源分支或 commit(默认 `master`) | +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +POST /v1/{owner}/{repo}/branches +Body: { "new_branch_name": name, "old_branch_name": from } +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "name": "feature/new-feature", + "commit_id": "abc123...", + "commit_message": "Create feature branch", + "committed_time": "2026-01-01T00:00:00Z" + } +} +``` + +## Workflow + +1. **Confirm** the branch name and source branch with the user. +2. **Execute** `gitlink-cli branch +create --name --from `. +3. **Report** the created branch information. + +> [!CAUTION] +> This is a **Write Operation** — confirm user intent before executing. + +## Use Cases + +- **功能开发**:为新功能创建独立分支 +- **Bug 修复**:从稳定分支创建 hotfix 分支 +- **实验性功能**:创建实验分支进行尝试 +- **版本发布**:为发布版本创建分支 + +## Best Practices + +- **命名规范**:使用有意义的分支名,如 `feature/xxx`、`hotfix/xxx`、`release/xxx` +- **源分支选择**:通常从 `develop` 或 `master` 创建功能分支 +- **分支描述**:创建后可以添加描述说明分支用途 + +## Error Handling + +常见错误及解决方案: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `404` | 仓库不存在 | 检查 `--owner` 和 `--repo` 是否正确 | +| `409` | 分支已存在 | 使用不同的分支名或删除现有分支 | +| `404` | 源分支不存在 | 确认 `--from` 指定的分支或 commit 存在 | + +## Tips + +- 默认从 `master` 分支创建,如需从其他分支创建需明确指定 +- 分支名支持 `/` 分隔符,便于组织分支结构 +- 创建后可以立即使用 `gitlink-cli branch +list` 验证 + +## References + +- [branch +list](branch-list.md) — 列出分支 +- [branch +delete](branch-delete.md) — 删除分支 +- [gitlink-branch](../SKILL.md) — 分支操作总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/gitlink-branch/references/branch-delete.md b/skills/gitlink-branch/references/branch-delete.md new file mode 100644 index 0000000..46b3e84 --- /dev/null +++ b/skills/gitlink-branch/references/branch-delete.md @@ -0,0 +1,119 @@ +# branch +delete + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +删除指定的分支。**此操作不可逆,请谨慎使用。** + +## 命令 + +```bash +# 删除分支 +gitlink-cli branch +delete --name feature/old-feature + +# 指定仓库删除分支 +gitlink-cli branch +delete --name feature/old-feature --owner someone --repo myrepo + +# 删除带路径的分支 +gitlink-cli branch +delete --name feature/my-feature +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--name, -n` | **是** | 要删除的分支名称 | +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +POST /v1/{owner}/{repo}/branches/delete +Body: { "branch_name": name } +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "message": "Branch deleted successfully", + "branch_name": "feature/old-feature" + } +} +``` + +## Workflow + +1. **Confirm** the user really wants to delete this branch (emphasize this is **irreversible**). +2. **Check** if the branch exists using `branch +list` if needed. +3. **Execute** `gitlink-cli branch +delete --name `. +4. **Report** the deletion result. + +> [!CAUTION] +> This is a **Destructive Operation** — confirm user intent before executing. This action **cannot be undone**. + +## Use Cases + +- **清理已完成的功能分支**:功能合并后删除功能分支 +- **清理错误的分支**:删除创建错误或不再需要的分支 +- **维护分支整洁**:定期清理无用分支保持仓库整洁 + +## Warnings + +- ⚠️ **不可逆操作**:删除分支后无法恢复 +- ⚠️ **受保护分支**:无法删除受保护的分支 +- ⚠️ **默认分支**:无法删除默认分支(通常是 master) +- ⚠️ **未合并更改**:删除包含未合并更改的分支可能导致代码丢失 + +## Best Practices + +1. **确认合并状态**:删除前确认分支的更改已经合并 +2. **备份重要更改**:如果有重要更改未合并,先备份或合并 +3. **沟通确认**:团队协作时先沟通确认再删除 +4. **使用描述性名称**:避免删除错误的分支 + +## Error Handling + +常见错误及解决方案: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `404` | 分支不存在 | 使用 `branch +list` 确认分支存在 | +| `403` | 权限不足 | 确认有删除分支的权限 | +| `400` | 受保护分支 | 无法删除受保护的分支 | +| `400` | 默认分支 | 无法删除默认分支 | + +## Safety Checks + +建议在删除前执行以下检查: + +```bash +# 1. 检查分支是否存在 +gitlink-cli branch +list | grep branch-name + +# 2. 确认不是保护分支 +gitlink-cli branch +list --format json | jq '.data.branches[] | select(.name=="branch-name") | .protected' + +# 3. 确认不是默认分支 +gitlink-cli api GET /{owner}/{repo} | jq '.data.default_branch' +``` + +## Tips + +- 删除前建议使用 `gitlink-cli branch +list` 确认分支名称 +- 对于重要分支,建议先检查是否有未合并的 PR +- 团队协作时,删除公共分支前先通知团队成员 + +## References + +- [branch +list](branch-list.md) — 列出分支 +- [branch +create](branch-create.md) — 创建分支 +- [branch +protect](branch-protect.md) — 保护分支 +- [gitlink-branch](../SKILL.md) — 分支操作总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/gitlink-branch/references/branch-list.md b/skills/gitlink-branch/references/branch-list.md new file mode 100644 index 0000000..a9eb3db --- /dev/null +++ b/skills/gitlink-branch/references/branch-list.md @@ -0,0 +1,103 @@ +# branch +list + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +列出仓库的所有分支,支持分页查询。 + +## 命令 + +```bash +# 列出当前仓库的分支 +gitlink-cli branch +list + +# 指定仓库并分页 +gitlink-cli branch +list --owner Gitlink --repo forgeplus --page 1 --limit 10 + +# 输出为 JSON +gitlink-cli branch +list --format json + +# 输出为 YAML +gitlink-cli branch +list --format yaml +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--page, -p` | 否 | 页码(默认 `1`) | +| `--limit, -l` | 否 | 每页条数(默认 `20`) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +GET /v1/{owner}/{repo}/branches?page=1&limit=20 +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "branches": [ + { + "name": "master", + "commit_id": "abc123...", + "commit_message": "Initial commit", + "committed_time": "2026-01-01T00:00:00Z", + "is_default": true, + "protected": false + }, + { + "name": "develop", + "commit_id": "def456...", + "commit_message": "Develop branch", + "committed_time": "2026-01-02T00:00:00Z", + "is_default": false, + "protected": true + } + ], + "total_count": 15 + }, + "meta": { + "page": 1, + "limit": 20, + "total_count": 15 + } +} +``` + +## Workflow + +1. **Resolve** owner and repo (from git remote or flags). +2. **Execute** `gitlink-cli branch +list`. +3. **Display** branches in the requested format. + +> [!NOTE] +> This is a **Read Operation** — no confirmation needed. + +## Use Cases + +- **查看可用分支**:在创建 PR 前查看所有分支 +- **检查分支保护状态**:查看哪些分支被保护 +- **分支浏览**:探索仓库的分支结构 +- **自动化脚本**:结合 JSON 格式输出进行批量操作 + +## Tips + +- 使用 `--format json` 可以更好地解析分支信息 +- 分支列表包含保护状态,可以快速识别受保护的分支 +- 支持分页,适合分支较多的仓库 + +## References + +- [branch +create](branch-create.md) — 创建分支 +- [branch +protect](branch-protect.md) — 保护分支 +- [gitlink-branch](../SKILL.md) — 分支操作总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/gitlink-branch/references/branch-protect.md b/skills/gitlink-branch/references/branch-protect.md new file mode 100644 index 0000000..f686be9 --- /dev/null +++ b/skills/gitlink-branch/references/branch-protect.md @@ -0,0 +1,142 @@ +# branch +protect + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +设置分支保护规则,防止重要分支被意外修改或删除。 + +## 命令 + +```bash +# 保护分支 +gitlink-cli branch +protect --name main + +# 保护 master 分支 +gitlink-cli branch +protect --name master + +# 指定仓库保护分支 +gitlink-cli branch +protect --name main --owner someone --repo myrepo + +# 保护开发分支 +gitlink-cli branch +protect --name develop +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--name, -n` | **是** | 要保护的分支名称 | +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +POST /{owner}/{repo}/protected_branches +Body: { "branch_name": name } +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "branch_name": "main", + "protected": true, + "message": "Branch protection enabled successfully" + } +} +``` + +## Workflow + +1. **Confirm** the branch name to protect with the user. +2. **Execute** `gitlink-cli branch +protect --name `. +3. **Report** the protection result. + +> [!CAUTION] +> This is a **Write Operation** — confirm user intent before executing. + +## Use Cases + +- **保护主分支**:保护 `main` 或 `master` 分支,防止直接推送 +- **保护发布分支**:保护 `release` 分支,确保发布版本稳定性 +- **保护开发分支**:保护 `develop` 分支,维护开发主线稳定 +- **合规要求**:满足团队管理或合规性要求 + +## What Protection Means + +分支保护后,以下操作将被限制: +- ✅ **仍可操作**:通过 Pull Request 合并更改 +- ❌ **受限操作**:直接推送代码 +- ❌ **受限操作**:强制推送 +- ❌ **受限操作**:删除分支 +- ❌ **受限操作**:修改历史 + +## Best Practices + +1. **保护关键分支**:至少保护 `main` 和 `develop` 分支 +2. **配合 PR 工作流**:强制通过 PR 进行代码审查 +3. **定期审查**:定期检查和保护重要的分支 +4. **团队协作**:团队协商确定保护策略 + +## Common Protected Branches + +| 分支名 | 用途 | 建议保护 | +|--------|------|----------| +| `main` / `master` | 主分支 | ✅ 强烈建议 | +| `develop` | 开发分支 | ✅ 建议 | +| `release/*` | 发布分支 | ✅ 建议 | +| `hotfix/*` | 紧急修复分支 | ⚠️ 可选 | + +## Error Handling + +常见错误及解决方案: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `404` | 分支不存在 | 使用 `branch +list` 确认分支存在 | +| `403` | 权限不足 | 确认有管理权限 | +| `409` | 已经被保护 | 分支已经处于保护状态 | + +## Safety Considerations + +- ⚠️ **权限要求**:需要管理员或协作者权限 +- ⚠️ **团队影响**:保护分支影响整个团队的协作流程 +- ⚠️ **CI/CD 集成**:确保 CI/CD 流程兼容保护规则 + +## Tips + +- 保护前先确认分支名称正确 +- 可以使用 `branch +list --format json` 查看分支保护状态 +- 设置保护后,团队成员需要通过 PR 贡献代码 +- 建议在设置保护前通知团队成员 + +## Workflow Example + +典型的分支保护工作流: + +```bash +# 1. 查看分支列表 +gitlink-cli branch +list + +# 2. 确认要保护的分支 +gitlink-cli branch +list --format json | jq '.data.branches[] | select(.name=="main")' + +# 3. 设置分支保护 +gitlink-cli branch +protect --name main + +# 4. 验证保护设置 +gitlink-cli branch +list --format json | jq '.data.branchs[] | select(.name=="main") | .protected' +``` + +## References + +- [branch +unprotect](branch-unprotect.md) — 移除分支保护 +- [branch +list](branch-list.md) — 列出分支并查看保护状态 +- [gitlink-branch](../SKILL.md) — 分支操作总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/gitlink-branch/references/branch-unprotect.md b/skills/gitlink-branch/references/branch-unprotect.md new file mode 100644 index 0000000..8a9aa88 --- /dev/null +++ b/skills/gitlink-branch/references/branch-unprotect.md @@ -0,0 +1,164 @@ +# branch +unprotect + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +移除分支保护规则,允许分支被直接修改。 + +## 命令 + +```bash +# 移除分支保护 +gitlink-cli branch +unprotect --name main + +# 指定仓库移除分支保护 +gitlink-cli branch +unprotect --name main --owner someone --repo myrepo + +# 移除开发分支保护 +gitlink-cli branch +unprotect --name develop +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--name, -n` | **是** | 要移除保护的分支名称 | +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +DELETE /{owner}/{repo}/protected_branches/{branch_name} +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "branch_name": "main", + "protected": false, + "message": "Branch protection removed successfully" + } +} +``` + +## Workflow + +1. **Confirm** the branch name to unprotect with the user. +2. **Execute** `gitlink-cli branch +unprotect --name `. +3. **Report** the unprotection result. + +> [!CAUTION] +> This is a **Write Operation** — confirm user intent before executing. This will allow direct pushes to the branch. + +## Use Cases + +- **紧急修复**:临时允许直接推送紧急修复 +- **分支重组**:调整分支保护策略 +- **迁移工作流**:从 PR 工作流切换到直接推送 +- **权限调整**:根据团队需求调整保护规则 + +## What Unprotection Means + +移除分支保护后,以下操作将被允许: +- ✅ **允许操作**:直接推送代码 +- ✅ **允许操作**:强制推送 +- ✅ **允许操作**:删除分支 +- ✅ **允许操作**:修改历史 + +## Risks and Considerations + +⚠️ **风险提醒**: +- 失去 PR 代码审查机制 +- 可能直接推送到关键分支 +- 增加代码冲突和错误风险 +- 影响代码质量和稳定性 + +## Best Practices + +1. **谨慎使用**:仅在确有需要时移除保护 +2. **临时移除**:考虑临时移除后重新保护 +3. **团队沟通**:移除保护前通知团队成员 +4. **重新保护**:完成操作后及时恢复保护 + +## When to Use + +**适合移除保护的情况:** +- 紧急修复需要快速部署 +- 仓库结构重组或迁移 +- 测试和验证工作流 +- 小团队内部协作 + +**不适合移除保护的情况:** +- 有 PR 审查需求 +- 多人协作的大型项目 +- 需要严格代码质量控制 +- 生产环境的关键分支 + +## Error Handling + +常见错误及解决方案: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `404` | 分支不存在 | 使用 `branch +list` 确认分支存在 | +| `404` | 未被保护 | 分支当前没有保护规则 | +| `403` | 权限不足 | 确认有管理权限 | +| `400` | 路径问题 | 含 `/` 的分支名可能需要通过 Web 操作 | + +## Limitations + +- ⚠️ **路径限制**:含 `/` 的分支名(如 `feature/my-branch`)可能无法通过 CLI 移除保护 +- ⚠️ **API 限制**:某些特殊分支可能需要通过 Web 页面操作 +- ⚠️ **权限要求**:需要管理员或协作者权限 + +## Safety Workflow + +推荐的移除保护工作流: + +```bash +# 1. 查看当前保护状态 +gitlink-cli branch +list --format json | jq '.data.branches[] | select(.protected)' + +# 2. 确认要移除保护的分支 +gitlink-cli branch +list --format json | jq '.data.branches[] | select(.name=="main") | .protected' + +# 3. 移除分支保护 +gitlink-cli branch +unprotect --name main + +# 4. 验证移除结果 +gitlink-cli branch +list --format json | jq '.data.branches[] | select(.name=="main") | .protected' + +# 5. 完成操作后重新保护 +gitlink-cli branch +protect --name main +``` + +## Tips + +- 移除保护前,建议先检查当前的保护状态 +- 考虑设置定时提醒,确保及时恢复保护 +- 对于重要分支,建议使用 Web UI 确认移除保护 +- 记录移除保护的原因和时间,便于审计 + +## Team Collaboration + +团队协作时的建议: + +1. **提前沟通**:在移除保护前通知所有团队成员 +2. **说明原因**:向团队解释为什么需要移除保护 +3. **时间限制**:设定移除保护的时间限制 +4. **操作文档**:记录移除保护的操作和原因 +5. **及时恢复**:完成操作后立即恢复保护 + +## References + +- [branch +protect](branch-protect.md) — 设置分支保护 +- [branch +list](branch-list.md) — 列出分支并查看保护状态 +- [gitlink-branch](../SKILL.md) — 分支操作总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/gitlink-ci/references/ci-list.md b/skills/gitlink-ci/references/ci-list.md new file mode 100644 index 0000000..9c11d54 --- /dev/null +++ b/skills/gitlink-ci/references/ci-list.md @@ -0,0 +1,180 @@ +# ci +builds + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +列出仓库的所有 CI/CD 构建记录,支持分页查询。 + +## 命令 + +```bash +# 查看当前仓库的构建列表 +gitlink-cli ci +builds + +# 指定仓库查看构建 +gitlink-cli ci +builds --owner myuser --repo myrepo + +# 分页查询 +gitlink-cli ci +builds --page 2 --limit 10 + +# 输出为 JSON 格式 +gitlink-cli ci +builds --format json +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--page, -p` | 否 | 页码(默认 `1`) | +| `--limit, -l` | 否 | 每页条数(默认 `20`) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +GET /{owner}/{repo}/builds?page=1&limit=20 +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "builds": [ + { + "id": 42, + "build_number": 42, + "status": "success", + "started_at": "2026-01-01T10:00:00Z", + "duration": 125, + "commit": { + "sha": "abc123...", + "message": "Fix bug in authentication", + "author": "developer@example.com" + }, + "branch": "feature/auth-fix", + "stages": [ + { + "stage_number": 1, + "stage_name": "build", + "status": "success" + }, + { + "stage_number": 2, + "stage_name": "test", + "status": "success" + } + ] + }, + { + "id": 41, + "build_number": 41, + "status": "failed", + "started_at": "2026-01-01T09:30:00Z", + "duration": 45, + "commit": { + "sha": "def456...", + "message": "Add new feature", + "author": "developer@example.com" + }, + "branch": "develop", + "stages": [ + { + "stage_number": 1, + "stage_name": "build", + "status": "failed" + } + ] + } + ], + "total_count": 156 + }, + "meta": { + "page": 1, + "limit": 20, + "total_count": 156 + } +} +``` + +## Workflow + +1. **Resolve** owner and repo (from git remote or flags). +2. **Execute** `gitlink-cli ci +builds`. +3. **Display** builds in the requested format. + +> [!NOTE] +> This is a **Read Operation** — no confirmation needed. + +## Use Cases + +- **构建历史查看**:查看仓库的构建历史和状态 +- **问题排查**:查找失败的构建进行分析 +- **构建监控**:监控 CI/CD 系统的运行状态 +- **自动化脚本**:结合 JSON 格式输出进行构建分析 + +## Build Status + +构建状态类型: + +| 状态 | 说明 | +|------|------| +| `pending` | 等待执行 | +| `running` | 正在执行 | +| `success` | 构建成功 | +| `failed` | 构建失败 | +| `cancelled` | 构建取消 | +| `skipped` | 构建跳过 | + +## Data Analysis + +使用 JSON 输出进行构建分析: + +```bash +# 查看最近10次构建的成功率 +gitlink-cli ci +builds --format json --limit 10 | \ + jq '[.data.builds[] | select(.status=="success")] | length / 10 * 100' + +# 查看失败的构建 +gitlink-cli ci +builds --format json | \ + jq '.data.builds[] | select(.status=="failed")' + +# 查看平均构建时间 +gitlink-cli ci +builds --format json | \ + jq '[.data.builds[].duration] | add / length' +``` + +## Tips + +- 使用 `--format json` 可以更好地解析和分析构建数据 +- 构建列表包含详细的提交信息和分支信息 +- 支持分页,适合构建历史较多的仓库 +- 结合 `ci +logs` 可以深入分析构建失败原因 + +## CI/CD Integration + +结合其他 CI 命令的典型工作流: + +```bash +# 1. 查看构建列表 +gitlink-cli ci +builds + +# 2. 查看失败构建的日志 +gitlink-cli ci +logs --build 42 + +# 3. 重启失败的构建 +gitlink-cli ci +restart --build 42 +``` + +## References + +- [ci +logs](ci-logs.md) — 查看构建日志 +- [ci +restart](ci-restart.md) — 重启构建 +- [ci +stop](ci-stop.md) — 停止构建 +- [gitlink-ci](../SKILL.md) — CI/CD 操作总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/gitlink-ci/references/ci-logs.md b/skills/gitlink-ci/references/ci-logs.md new file mode 100644 index 0000000..4599c72 --- /dev/null +++ b/skills/gitlink-ci/references/ci-logs.md @@ -0,0 +1,204 @@ +# ci +logs + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +查看指定 CI 构建的详细日志输出。 + +## 命令 + +```bash +# 查看构建日志 +gitlink-cli ci +logs --build 42 + +# 查看特定阶段的日志 +gitlink-cli ci +logs --build 42 --stage 2 + +# 查看特定步骤的日志 +gitlink-cli ci +logs --build 42 --stage 2 --step 3 + +# 指定仓库查看日志 +gitlink-cli ci +logs --build 42 --owner myuser --repo myrepo +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--build, -b` | **是** | 构建编号 | +| `--stage, -s` | 否 | 阶段编号(默认 `1`) | +| `--step` | 否 | 步骤编号(默认 `1`) | +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +GET /{owner}/{repo}/builds/{build}/logs/{stage}/{step} +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "build_number": 42, + "stage_number": 2, + "step_number": 1, + "log_content": "Running tests...\nTest suite started...\n[OK] Test authentication\n[OK] Test database connection\n[FAILED] Test API endpoint\n\nTests completed: 2/3 passed", + "stage_name": "test", + "step_name": "run_tests", + "timestamp": "2026-01-01T10:05:30Z" + } +} +``` + +## Workflow + +1. **Confirm** the build number with the user (can use `ci +builds` to list). +2. **Execute** `gitlink-cli ci +logs --build [--stage ] [--step ]`. +3. **Display** the log content. + +> [!NOTE] +> This is a **Read Operation** — no confirmation needed. + +## Use Cases + +- **问题排查**:查看构建失败的具体原因 +- **性能分析**:分析构建过程中的性能瓶颈 +- **调试输出**:查看代码运行时的调试信息 +- **监控执行**:实时跟踪构建执行状态 + +## CI Pipeline Structure + +典型的 CI/CD 流水线结构: + +``` +Stage 1: Build + ├── Step 1: Install dependencies + ├── Step 2: Build application + └── Step 3: Run linters + +Stage 2: Test + ├── Step 1: Run unit tests + ├── Step 2: Run integration tests + └── Step 3: Generate coverage report + +Stage 3: Deploy + ├── Step 1: Build deployment package + └── Step 2: Deploy to server +``` + +## Log Analysis + +日志分析技巧: + +```bash +# 查看构建日志 +gitlink-cli ci +logs --build 42 --stage 2 --step 1 + +# 结合 grep 过滤关键错误 +gitlink-cli ci +logs --build 42 --format json | \ + jq '.data.log_content' | grep "ERROR" + +# 查看完整日志流 +gitlink-cli ci +logs --build 42 --format json | \ + jq -r '.data.log_content' +``` + +## Stage and Step Navigation + +查看不同阶段的日志: + +```bash +# Stage 1: Build stage +gitlink-cli ci +logs --build 42 --stage 1 --step 1 + +# Stage 2: Test stage +gitlink-cli ci +logs --build 42 --stage 2 --step 1 + +# Stage 3: Deploy stage +gitlink-cli ci +logs --build 42 --stage 3 --step 1 +``` + +## Common Log Patterns + +常见日志模式: + +| 模式 | 含义 | +|------|------| +| `[ERROR]` | 错误信息 | +| `[FAILED]` | 测试或步骤失败 | +| `[WARN]` | 警告信息 | +| `[OK]` | 操作成功 | +| `Running...` | 正在执行 | +| `Completed` | 执行完成 | + +## Tips + +- 先使用 `ci +builds` 确认构建编号 +- 构建通常包含多个阶段,需要指定正确的阶段编号 +- 日志内容可能很长,建议使用 `--format json` 便于解析 +- 结合构建状态可以快速定位问题 + +## Troubleshooting Workflow + +典型的故障排查工作流: + +```bash +# 1. 查看构建列表,找到失败的构建 +gitlink-cli ci +builds | grep "failed" + +# 2. 查看失败构建的详细状态 +gitlink-cli ci +builds --build 42 --format json | \ + jq '.data.builds[] | .stages[]' + +# 3. 查看失败阶段的日志 +gitlink-cli ci +logs --build 42 --stage 2 --step 1 + +# 4. 根据日志信息修复问题 + +# 5. 重启构建 +gitlink-cli ci +restart --build 42 +``` + +## Error Handling + +常见错误及解决方案: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `404` | 构建不存在 | 检查构建编号是否正确 | +| `404` | 阶段或步骤不存在 | 确认阶段和步骤编号 | +| `403` | 权限不足 | 确认有查看该仓库构建的权限 | + +## Advanced Usage + +高级用法示例: + +```bash +# 导出构建日志到文件 +gitlink-cli ci +logs --build 42 --format json | \ + jq -r '.data.log_content' > build_42_logs.txt + +# 分析日志中的错误模式 +gitlink-cli ci +logs --build 42 --format json | \ + jq -r '.data.log_content' | grep -c "ERROR" + +# 查看所有阶段的日志(循环) +for stage in {1..3}; do + echo "=== Stage $stage ===" + gitlink-cli ci +logs --build 42 --stage $stage --step 1 +done +``` + +## References + +- [ci +builds](ci-list.md) — 查看构建列表 +- [ci +restart](ci-restart.md) — 重启构建 +- [gitlink-ci](../SKILL.md) — CI/CD 操作总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/gitlink-ci/references/ci-restart.md b/skills/gitlink-ci/references/ci-restart.md new file mode 100644 index 0000000..a169745 --- /dev/null +++ b/skills/gitlink-ci/references/ci-restart.md @@ -0,0 +1,201 @@ +# ci +restart + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +重新启动失败的或取消的 CI 构建。 + +## 命令 + +```bash +# 重启构建 +gitlink-cli ci +restart --build 42 + +# 指定仓库重启构建 +gitlink-cli ci +restart --build 42 --owner myuser --repo myrepo + +# 重启失败的构建(JSON 输出) +gitlink-cli ci +restart --build 42 --format json +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--build, -b` | **是** | 构建编号 | +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +POST /{owner}/{repo}/builds/{build}/restart +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "old_build_number": 42, + "new_build_number": 43, + "status": "pending", + "message": "Build restarted successfully", + "triggered_at": "2026-01-01T11:00:00Z" + } +} +``` + +## Workflow + +1. **Confirm** the build number to restart with the user. +2. **Check** the current build status (optional, using `ci +builds`). +3. **Execute** `gitlink-cli ci +restart --build `. +4. **Report** the restart result and new build number. + +> [!CAUTION] +> This is a **Write Operation** — confirm user intent before executing. + +## Use Cases + +- **失败重试**:构建因临时问题失败后重试 +- **取消后重新执行**:构建被取消后需要重新执行 +- **代码修复后验证**:修复代码后重新验证构建 +- **环境问题恢复**:CI 环境问题恢复后重新构建 + +## When to Restart + +**适合重启的情况:** +- ✅ 构建因临时网络问题失败 +- ✅ 依赖服务暂时不可用 +- ✅ 代码修复后需要重新验证 +- ✅ CI 环境问题已解决 + +**不适合重启的情况:** +- ❌ 代码存在严重错误 +- ❌ 测试用例本身有问题 +- ❌ 构建配置需要修改 +- ❌ 依赖库版本不兼容 + +## Restart Behavior + +重启构建的行为特点: + +| 方面 | 说明 | +|------|------| +| **新构建编号** | 重启会创建新的构建编号 | +| **相同代码** | 使用相同的提交代码 | +| **相同环境** | 使用相同的构建环境 | +| **独立日志** | 新构建有独立的日志记录 | +| **状态继承** | 不会继承原构建的状态 | + +## Best Practices + +1. **查看日志**:重启前先查看失败原因 +2. **修复问题**:如果是代码问题,先修复再重启 +3. **监控新构建**:重启后监控新构建的执行状态 +4. **资源考虑**:频繁重启会消耗 CI 资源 + +## Troubleshooting Workflow + +典型的故障排查和重启流程: + +```bash +# 1. 查看构建列表,找到失败的构建 +gitlink-cli ci +builds | grep "failed" + +# 2. 查看失败构建的详细状态 +gitlink-cli ci +builds --format json | \ + jq '.data.builds[] | select(.build_number==42)' + +# 3. 查看失败阶段的日志 +gitlink-cli ci +logs --build 42 --stage 2 --step 1 + +# 4. 分析日志,确定失败原因 + +# 5. 如果是临时问题,重启构建 +gitlink-cli ci +restart --build 42 + +# 6. 如果是代码问题,修复后重启 +# (先修复代码,然后) +gitlink-cli ci +restart --build 42 +``` + +## Error Handling + +常见错误及解决方案: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `404` | 构建不存在 | 检查构建编号是否正确 | +| `400` | 构建正在运行 | 正在运行的构建无法重启 | +| `403` | 权限不足 | 确认有操作该仓库构建的权限 | +| `429` | 重启次数过多 | 短时间内重启次数过多,等待后重试 | + +## Pre-Restart Checklist + +重启前检查清单: + +- [ ] 确认构建编号正确 +- [ ] 查看失败日志,了解失败原因 +- [ ] 确认问题已解决(如果是代码问题) +- [ ] 检查 CI 系统状态 +- [ ] 确认有足够的 CI 资源 +- [ ] 考虑是否需要修改构建配置 + +## Post-Restart Actions + +重启后的后续操作: + +```bash +# 1. 重启构建 +gitlink-cli ci +restart --build 42 + +# 2. 获取新构建编号 +gitlink-cli ci +restart --build 42 --format json | \ + jq '.data.new_build_number' + +# 3. 监控新构建状态 +gitlink-cli ci +builds --format json | \ + jq '.data.builds[0]' + +# 4. 查看新构建的日志(如需要) +gitlink-cli ci +logs --build 43 --stage 1 --step 1 +``` + +## Team Collaboration + +团队协作时的建议: + +1. **沟通确认**:重启构建前通知相关团队成员 +2. **记录原因**:记录重启的原因和时间 +3. **状态更新**:及时更新构建状态给团队 +4. **结果分享**:重启完成后分享结果 + +## Tips + +- 重启会创建新的构建编号,原构建历史仍保留 +- 重启前建议先查看日志,确认问题性质 +- 对于重复失败的情况,建议先修复根本原因 +- 可以通过 `ci +builds` 查看重启后的新构建状态 + +## Cost Considerations + +使用注意事项: + +- ⚠️ **资源消耗**:每次重启都会消耗 CI 资源 +- ⚠️ **时间成本**:重新执行完整的构建流程 +- ⚠️ **排队时间**:新构建可能需要排队等待 +- ⚠️ **频繁重启**:避免无意义的频繁重启 + +## References + +- [ci +builds](ci-list.md) — 查看构建列表 +- [ci +logs](ci-logs.md) — 查看构建日志 +- [ci +stop](ci-stop.md) — 停止构建 +- [gitlink-ci](../SKILL.md) — CI/CD 操作总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/gitlink-ci/references/ci-stop.md b/skills/gitlink-ci/references/ci-stop.md new file mode 100644 index 0000000..af7f7e6 --- /dev/null +++ b/skills/gitlink-ci/references/ci-stop.md @@ -0,0 +1,245 @@ +# ci +stop + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +停止正在运行的 CI 构建。 + +## 命令 + +```bash +# 停止构建 +gitlink-cli ci +stop --build 42 + +# 指定仓库停止构建 +gitlink-cli ci +stop --build 42 --owner myuser --repo myrepo + +# 停止构建(JSON 输出) +gitlink-cli ci +stop --build 42 --format json +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--build, -b` | **是** | 构建编号 | +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +DELETE /{owner}/{repo}/builds/{build}/stop +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "build_number": 42, + "status": "cancelled", + "message": "Build stopped successfully", + "stopped_at": "2026-01-01T11:30:00Z", + "duration": 180 + } +} +``` + +## Workflow + +1. **Confirm** the build number to stop with the user. +2. **Check** the current build status (ensure it's running). +3. **Execute** `gitlink-cli ci +stop --build `. +4. **Report** the stop result. + +> [!CAUTION] +> This is a **Write Operation** — confirm user intent before executing. This will terminate a running build. + +## Use Cases + +- **错误停止**:构建出现错误需要立即停止 +- **资源释放**:释放 CI 资源给其他构建 +- **配置错误**:构建配置错误需要停止 +- **测试中止**:测试过程中发现问题需要中止 +- **时间限制**:构建时间过长需要停止 + +## When to Stop + +**适合停止的情况:** +- ✅ 构建明显出现错误,继续执行无意义 +- ✅ 发现严重bug,需要立即停止 +- ✅ 构建配置错误,需要修改后重新执行 +- ✅ 误触发构建,需要立即取消 +- ✅ 构建时间过长,超出预期 + +**不适合停止的情况:** +- ❌ 构建接近完成 +- ❌ 仅为节省时间而停止正常构建 +- ❌ 不确定构建是否有问题 + +## Stop Behavior + +停止构建的行为特点: + +| 方面 | 说明 | +|------|------| +| **立即停止** | 通常会立即中断构建执行 | +| **状态变更** | 构建状态变为 `cancelled` | +| **资源释放** | 释放 CI 计算资源 | +| **日志保留** | 已执行的日志会保留 | +| **不可恢复** | 停止的构建无法恢复执行 | + +## Safety Considerations + +停止构建前考虑: + +- ⚠️ **进度损失**:已执行的进度会丢失 +- ⚠️ **资源浪费**:已消耗的资源无法回收 +- ⚠️ **团队影响**:可能影响其他依赖此构建的任务 +- ⚠️ **重新执行**:需要重新启动完整的构建 + +## Best Practices + +1. **确认状态**:停止前确认构建确实在运行 +2. **评估影响**:考虑停止对其他流程的影响 +3. **记录原因**:记录停止构建的原因 +4. **后续处理**:计划停止后的后续操作 + +## Stop Workflow + +典型的停止构建工作流: + +```bash +# 1. 查看运行中的构建 +gitlink-cli ci +builds --format json | \ + jq '.data.builds[] | select(.status=="running")' + +# 2. 确认要停止的构建编号 +gitlink-cli ci +builds | grep "running" + +# 3. 停止构建 +gitlink-cli ci +stop --build 42 + +# 4. 验证停止状态 +gitlink-cli ci +builds --format json | \ + jq '.data.builds[] | select(.build_number==42) | .status' +``` + +## Error Handling + +常见错误及解决方案: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `404` | 构建不存在 | 检查构建编号是否正确 | +| `400` | 构建已完成 | 构建已经完成或停止,无法再停止 | +| `403` | 权限不足 | 确认有操作该仓库构建的权限 | +| `409` | 构建已完成 | 构建已经自然结束 | + +## Pre-Stop Checklist + +停止前检查清单: + +- [ ] 确认构建编号正确 +- [ ] 确认构建正在运行 +- [ ] 评估停止的影响范围 +- [ ] 确认停止原因合理 +- [ ] 考虑后续处理方案 +- [ ] 通知相关团队成员 + +## Post-Stop Actions + +停止后的后续操作: + +```bash +# 1. 停止构建 +gitlink-cli ci +stop --build 42 + +# 2. 查看停止状态 +gitlink-cli ci +builds --format json | \ + jq '.data.builds[] | select(.build_number==42)' + +# 3. 查看已执行的日志 +gitlink-cli ci +logs --build 42 --stage 1 --step 1 + +# 4. 根据需要重启构建 +gitlink-cli ci +restart --build 42 +``` + +## Common Scenarios + +常见使用场景: + +### 场景1:发现严重错误 +```bash +# 查看运行中的构建 +gitlink-cli ci +builds | grep "running" + +# 查看日志发现严重错误 +gitlink-cli ci +logs --build 42 --stage 2 --step 1 + +# 立即停止构建 +gitlink-cli ci +stop --build 42 +``` + +### 场景2:误触发构建 +```bash +# 发现误触发了构建 +gitlink-cli ci +builds | grep "running" + +# 立即停止误触发的构建 +gitlink-cli ci +stop --build 42 +``` + +### 场景3:配置错误 +```bash +# 发现构建配置错误 +gitlink-cli ci +logs --build 42 --stage 1 --step 1 + +# 停止当前构建 +gitlink-cli ci +stop --build 42 + +# 修复配置后重新构建 +# (修复配置) +gitlink-cli ci +restart --build 42 +``` + +## Team Collaboration + +团队协作时的建议: + +1. **及时通知**:停止构建前通知相关团队成员 +2. **说明原因**:向团队解释为什么需要停止构建 +3. **状态同步**:更新项目管理系统中的构建状态 +4. **后续计划**:告知团队停止后的处理计划 + +## Tips + +- 停止前建议先确认构建状态,避免重复操作 +- 查看构建日志可以帮助判断是否值得停止 +- 停止后可以考虑是否需要重启或修复后重新构建 +- 对于长时间运行的构建,定期检查状态可能更合适 + +## Alternatives + +替代方案考虑: + +| 情况 | 停止 | 等待完成 | 其他方案 | +|------|------|----------|----------| +| 严重错误 | ✅ 推荐 | ❌ 不推荐 | 修复后重启 | +| 临时问题 | ⚠️ 可选 | ✅ 推荐 | 等待自动恢复 | +| 配置错误 | ✅ 推荐 | ❌ 不推荐 | 修复配置后重启 | +| 时间过长 | ⚠️ 可选 | ✅ 推荐 | 优化构建流程 | + +## References + +- [ci +builds](ci-list.md) — 查看构建列表 +- [ci +logs](ci-logs.md) — 查看构建日志 +- [ci +restart](ci-restart.md) — 重启构建 +- [gitlink-ci](../SKILL.md) — CI/CD 操作总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/gitlink-pm/references/pm-kanban.md b/skills/gitlink-pm/references/pm-kanban.md new file mode 100644 index 0000000..ad4c9d2 --- /dev/null +++ b/skills/gitlink-pm/references/pm-kanban.md @@ -0,0 +1,254 @@ +# PM 看板管理 + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **注意**:PM 功能需要项目开启 PM 模块,并通过项目 ID 访问。 + +GitLink PM 看板功能提供项目任务的可视化管理,支持任务的拖拽、状态管理和团队协作。 + +## 命令 + +```bash +# 查看项目看板 +gitlink-cli api GET /pm/dashboards --query 'project_id=123' + +# 查看当前仓库的项目 ID +gitlink-cli repo +info --format json | jq '.data.project_id' + +# 组合命令:自动获取项目 ID 并查看看板 +PROJECT_ID=$(gitlink-cli repo +info --format json | jq -r '.data.project_id') +gitlink-cli api GET /pm/dashboards --query "project_id=$PROJECT_ID" +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `project_id` | **是** | 项目 ID(通过 `repo +info` 获取) | +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +GET /api/pm/dashboards?project_id={project_id} +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "dashboards": [ + { + "id": 1, + "name": "开发看板", + "description": "主开发任务看板", + "project_id": 123, + "columns": [ + { + "id": 1, + "name": "待处理", + "position": 1, + "issue_count": 5 + }, + { + "id": 2, + "name": "进行中", + "position": 2, + "issue_count": 3 + }, + { + "id": 3, + "name": "已完成", + "position": 3, + "issue_count": 8 + } + ], + "issues": [ + { + "id": 456, + "subject": "实现用户认证功能", + "status_id": 1, + "priority_id": 2, + "assigned_to": "developer1", + "column_id": 2, + "position": 1 + } + ] + } + ], + "total_count": 1 + } +} +``` + +## Workflow + +1. **Get Project ID** using `repo +info`. +2. **Execute** `gitlink-cli api GET /pm/dashboards --query 'project_id='`. +3. **Display** kanban board information. + +> [!NOTE] +> This is a **Read Operation** — no confirmation needed. + +## Use Cases + +- **任务可视化**:直观查看项目任务分布 +- **进度跟踪**:实时监控任务进展情况 +- **资源分配**:查看团队成员的工作负载 +- **流程管理**:管理任务的流转和状态变更 + +## Kanban Board Structure + +典型看板结构: + +``` +┌─────────────┬─────────────┬─────────────┐ +│ 待处理 │ 进行中 │ 已完成 │ +│ [5 tasks] │ [3 tasks] │ [8 tasks] │ +├─────────────┼─────────────┼─────────────┤ +│ Task 1 │ Task 6 │ Task 11 │ +│ Task 2 │ Task 7 │ Task 12 │ +│ Task 3 │ Task 8 │ Task 13 │ +│ Task 4 │ Task 9 │ Task 14 │ +│ Task 5 │ Task 10 │ Task 15 │ +└─────────────┴─────────────┴─────────────┘ +``` + +## Common Operations + +看板常用操作: + +### 查看任务分布 +```bash +# 查看各列的任务数量 +gitlink-cli api GET /pm/dashboards --query 'project_id=123' --format json | \ + jq '.data.dashboards[0].columns[] | {name: .name, count: .issue_count}' +``` + +### 查看特定任务 +```bash +# 查看"进行中"的任务 +gitlink-cli api GET /pm/dashboards --query 'project_id=123' --format json | \ + jq '.data.dashboards[0].issues[] | select(.column_id==2)' +``` + +### 统计工作负载 +```bash +# 按人员统计任务数量 +gitlink-cli api GET /pm/dashboards --query 'project_id=123' --format json | \ + jq '.data.dashboards[0].issues[] | group_by(.assigned_to) | map({assigned_to: .[0].assigned_to, count: length})' +``` + +## Task Management + +任务管理最佳实践: + +1. **列管理**:合理设置任务列(如:待处理、进行中、已完成) +2. **限制数量**:对"进行中"列设置 WIP 限制 +3. **定期清理**:及时移动已完成任务到相应列 +4. **优先级标记**:使用标签和优先级标识重要任务 + +## Analysis Examples + +看板数据分析示例: + +```bash +# 1. 获取项目 ID +PROJECT_ID=$(gitlink-cli repo +info --format json | jq -r '.data.project_id') + +# 2. 查看完整看板数据 +gitlink-cli api GET /pm/dashboards --query "project_id=$PROJECT_ID" --format json + +# 3. 分析任务瓶颈(找出任务最多的列) +gitlink-cli api GET /pm/dashboards --query "project_id=$PROJECT_ID" --format json | \ + jq '.data.dashboards[0].columns | sort_by(.issue_count) | reverse | .[0]' + +# 4. 计算完成率 +gitlink-cli api GET /pm/dashboards --query "project_id=$PROJECT_ID" --format json | \ + jq '[.data.dashboards[0].columns[] | select(.name=="已完成")] | .[0].issue_count / + [.data.dashboards[0].columns[].issue_count] | add * 100' +``` + +## Tips + +- 看板数据可以帮助识别项目瓶颈 +- 定期查看看板可以保持项目进度的可视化 +- 结合 Issue 操作可以实现完整的任务管理流程 +- 使用 JSON 格式输出便于自动化分析 + +## Integration with Other Features + +与其他功能集成: + +```bash +# 看板 + Issue 操作 +# 1. 查看看板中的任务 +gitlink-cli api GET /pm/dashboards --query 'project_id=123' --format json + +# 2. 查看特定任务详情 +gitlink-cli issue +view --issue 456 + +# 3. 更新任务状态 +gitlink-cli issue +update --issue 456 --status_id 3 +``` + +## Error Handling + +常见错误及解决方案: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `400` | PM 模块未开启 | 联系项目管理员开启 PM 模块 | +| `404` | 项目不存在 | 检查 project_id 是否正确 | +| `403` | 权限不足 | 确认有查看该项目的权限 | +| `404` | 看板不存在 | 该项目可能没有配置看板 | + +## Prerequisites + +使用 PM 功能的前置条件: + +1. **PM 模块开启**:项目需要开启 PM 功能模块 +2. **有效项目 ID**:需要正确的项目 ID +3. **访问权限**:需要该项目的访问权限 +4. **看板配置**:项目需要有配置的看板 + +## Setup Workflow + +PM 功能设置流程: + +```bash +# 1. 检查项目是否开启 PM +gitlink-cli repo +info --format json | jq '.data.has_pm' + +# 2. 获取项目 ID +gitlink-cli repo +info --format json | jq '.data.project_id' + +# 3. 查看看板配置 +gitlink-cli api GET /pm/dashboards --query 'project_id=123' + +# 4. 如需配置看板,通过 GitLink 网页端操作 +# https://www.gitlink.org.cn/{owner}/{repo}/project_modules +``` + +## Team Collaboration + +团队协作建议: + +1. **定期更新**:团队成员定期更新任务状态 +2. **明确规范**:制定看板使用规范和列定义 +3. **WIP 限制**:设置进行中任务的数量限制 +4. **定期回顾**:定期回顾看板数据,优化流程 + +## References + +- [pm-sprint](pm-sprint.md) — Sprint 管理 +- [pm-report](pm-report.md) — 周报生成 +- [gitlink-pm](../SKILL.md) — 项目管理总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 +- [repo +info](../../gitlink-repo/references/repo-info.md) — 获取仓库信息 diff --git a/skills/gitlink-pm/references/pm-report.md b/skills/gitlink-pm/references/pm-report.md new file mode 100644 index 0000000..a630eee --- /dev/null +++ b/skills/gitlink-pm/references/pm-report.md @@ -0,0 +1,400 @@ +# PM 周报生成 + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **注意**:PM 功能需要项目开启 PM 模块,并通过项目 ID 访问。 + +GitLink PM 周报功能提供项目一周工作情况的自动汇总,包括 Issue、Pull Request、提交记录等数据。 + +## 命令 + +```bash +# 查看周报数据 +gitlink-cli api GET /pm/weekly_issues --query 'project_id=123' + +# 查看当前仓库的项目 ID +gitlink-cli repo +info --format json | jq '.data.project_id' + +# 组合命令:自动获取项目 ID 并查看周报 +PROJECT_ID=$(gitlink-cli repo +info --format json | jq -r '.data.project_id') +gitlink-cli api GET /pm/weekly_issues --query "project_id=$PROJECT_ID" + +# 查看特定日期范围的周报 +gitlink-cli api GET /pm/weekly_issues --query 'project_id=123&start_date=2026-01-01&end_date=2026-01-07' + +# 查看 Issue 标签统计 +gitlink-cli api GET /pm/issue_tags --query 'project_id=123' +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `project_id` | **是** | 项目 ID(通过 `repo +info` 获取) | +| `start_date` | 否 | 开始日期(格式:YYYY-MM-DD) | +| `end_date` | 否 | 结束日期(格式:YYYY-MM-DD) | +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +GET /api/pm/weekly_issues?project_id={project_id}&start_date={start_date}&end_date={end_date} +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "period": { + "start_date": "2026-01-01", + "end_date": "2026-01-07", + "week_number": 1 + }, + "summary": { + "total_issues": 15, + "new_issues": 8, + "closed_issues": 5, + "in_progress_issues": 2, + "total_prs": 6, + "merged_prs": 4, + "total_commits": 42 + }, + "issues": [ + { + "id": 456, + "subject": "实现用户认证功能", + "status": "closed", + "author": "developer1", + "assigned_to": "developer2", + "created_at": "2026-01-02T10:00:00Z", + "closed_at": "2026-01-05T15:30:00Z", + "labels": ["feature", "authentication"] + } + ], + "pull_requests": [ + { + "id": 123, + "title": "Feature: User authentication", + "status": "merged", + "author": "developer1", + "merged_at": "2026-01-05T16:00:00Z", + "additions": 245, + "deletions": 18 + } + ], + "commits": [ + { + "id": "abc123", + "message": "Implement user login", + "author": "developer1", + "committed_date": "2026-01-03T14:20:00Z" + } + ], + "team_contributions": [ + { + "developer": "developer1", + "issues_created": 3, + "issues_closed": 2, + "prs_created": 2, + "prs_merged": 2, + "commits_count": 15 + } + ] + } +} +``` + +## Workflow + +1. **Get Project ID** using `repo +info`. +2. **Execute** `gitlink-cli api GET /pm/weekly_issues --query 'project_id='`. +3. **Display** weekly report data. + +> [!NOTE] +> This is a **Read Operation** — no confirmation needed. + +## Use Cases + +- **工作汇报**:自动生成周工作总结 +- **进度跟踪**:监控项目一周的进展情况 +- **团队管理**:了解团队成员的工作贡献 +- **数据分析**:分析项目发展趋势和效率 + +## Weekly Report Structure + +典型周报结构: + +``` +周报(2026-01-01 至 2026-01-07) + +## 概览统计 +- 新增 Issue:8 个 +- 关闭 Issue:5 个 +- 进行中 Issue:2 个 +- 合并 PR:4 个 +- 代码提交:42 次 + +## 详细内容 +### Issue 活动 +- 新建:8 个 Issue +- 完成:5 个 Issue +- 持续工作:2 个 Issue + +### Pull Request 活动 +- 创建:6 个 PR +- 合并:4 个 PR + +### 团队贡献 +- developer1:15 次提交,2 个合并 PR +- developer2:12 次提交,1 个合并 PR +``` + +## Common Operations + +周报常用操作: + +### 生成简明周报 +```bash +# 生成简明周报摘要 +gitlink-cli api GET /pm/weekly_issues --query 'project_id=123' --format json | \ + jq '# 周报摘要 + "\n## 项目周报 (\(.data.period.start_date) 至 \(.data.period.end_date))", + "\n### 统计概览", + "- 新增 Issue: \(.data.summary.new_issues) 个", + "- 完成 Issue: \(.data.summary.closed_issues) 个", + "- 合并 PR: \(.data.summary.merged_prs) 个", + "- 代码提交: \(.data.summary.total_commits) 次"' +``` + +### 分析团队贡献 +```bash +# 按贡献度排序团队成员 +gitlink-cli api GET /pm/weekly_issues --query 'project_id=123' --format json | \ + jq '.data.team_contributions | sort_by(.commits_count) | reverse | + .[] | "\(.developer): \(.commits_count) 次提交, \(.prs_merged) 个合并 PR"' +``` + +### 查看活动趋势 +```bash +# 按日期统计活动 +gitlink-cli api GET /pm/weekly_issues --query 'project_id=123' --format json | \ + jq '[.data.commits[] | .committed_date | split("T")[0]] | + group_by(.) | + map({date: .[0], count: length}) | + sort_by(.date)' +``` + +## Report Metrics + +周报关键指标: + +| 指标 | 说明 | 用途 | +|------|------|------| +| **新增 Issue 数** | 一周内新建的 Issue 数量 | 反映新需求产生速度 | +| **关闭 Issue 数** | 一周内关闭的 Issue 数量 | 反映问题解决速度 | +| **合并 PR 数** | 一周内合并的 PR 数量 | 反映代码集成速度 | +| **提交次数** | 一周内的代码提交次数 | 反映开发活跃度 | +| **参与人数** | 有贡献活动的团队成员数 | 反映团队参与度 | + +## Analysis Examples + +周报数据分析示例: + +```bash +# 1. 获取项目 ID +PROJECT_ID=$(gitlink-cli repo +info --format json | jq -r '.data.project_id') + +# 2. 查看完整周报 +gitlink-cli api GET /pm/weekly_issues --query "project_id=$PROJECT_ID" --format json + +# 3. 生成团队贡献排名 +gitlink-cli api GET /pm/weekly_issues --query "project_id=$PROJECT_ID" --format json | \ + jq '.data.team_contributions | sort_by(.commits_count) | reverse | + +# 4. 计算完成率 +gitlink-cli api GET /pm/weekly_issues --query "project_id=$PROJECT_ID" --format json | \ + jq '(.data.summary.closed_issues / .data.summary.new_issues * 100) | + "本周完成率: \(.)%"' + +# 5. 分析代码变更量 +gitlink-cli api GET /pm/weekly_issues --query "project_id=$PROJECT_ID" --format json | \ + jq '{additions: [.data.pull_requests[].additions] | add, + deletions: [.data.pull_requests[].deletions] | add, + net_change: ([.data.pull_requests[].additions] | add) - ([.data.pull_requests[].deletions] | add)}' +``` + +## Custom Report Generation + +自定义报告生成: + +```bash +# 生成 Markdown 格式的周报 +generate_weekly_report() { + PROJECT_ID=$(gitlink-cli repo +info --format json | jq -r '.data.project_id') + END_DATE=$(date +%Y-%m-%d) + START_DATE=$(date -d "7 days ago" +%Y-%m-%d) + + echo "# 项目周报 ($START_DATE 至 $END_DATE)" + echo "" + + gitlink-cli api GET /pm/weekly_issues \ + --query "project_id=$PROJECT_ID&start_date=$START_DATE&end_date=$END_DATE" \ + --format json | \ + jq -r ' + "## 概览统计", + "- 新增 Issue: \(.data.summary.new_issues) 个", + "- 完成 Issue: \(.data.summary.closed_issues) 个", + "- 合并 PR: \(.data.summary.merged_prs) 个", + "- 代码提交: \(.data.summary.total_commits) 次", + "", + "## 团队贡献", + (.data.team_contributions | sort_by(.commits_count) | reverse | + .[] | "- **\(.developer)**: \(.commits_count) 次提交, \(.prs_merged) 个合并 PR"), + "", + "## 主要完成", + (.data.issues[] | select(.status == "closed") | + "- [\(.subject)](#issue/\(.id)) - \(.assigned_to)"), + "", + "## 代码合并", + (.data.pull_requests[] | select(.status == "merged") | + "- [\(.title)](#pr/\(.id)) - \(.author) (+\(.additions) -\(.deletions))") + ' +} +``` + +## Tips + +- 周报数据可以帮助团队了解工作进展 +- 定期生成周报可以保持项目进度的可视化 +- 结合其他 PM 数据可以实现完整的项目管理 +- 使用 JSON 格式输出便于自动化报告生成 + +## Integration with Other Features + +与其他功能集成: + +```bash +# 周报 + 详细操作 +# 1. 生成周报概览 +gitlink-cli api GET /pm/weekly_issues --query 'project_id=123' --format json + +# 2. 查看特定 Issue 详情 +gitlink-cli issue +view --issue 456 + +# 3. 查看特定 PR 详情 +gitlink-cli pr +view --pr 123 +``` + +## Best Practices + +周报生成最佳实践: + +1. **定期生成**:每周固定时间生成周报 +2. **数据验证**:生成后验证数据的准确性 +3. **格式统一**:使用统一的报告格式 +4. **趋势分析**:比较不同周报的数据趋势 +5. **团队分享**:及时分享周报给团队成员 + +## Advanced Usage + +高级用法示例: + +```bash +# 比较两周的数据 +compare_weeks() { + PROJECT_ID=$(gitlink-cli repo +info --format json | jq -r '.data.project_id') + + # 本周数据 + THIS_WEEK=$(gitlink-cli api GET /pm/weekly_issues --query "project_id=$PROJECT_ID" --format json) + + # 上周数据(计算日期) + LAST_START=$(date -d "14 days ago" +%Y-%m-%d) + LAST_END=$(date -d "8 days ago" +%Y-%m-%d) + LAST_WEEK=$(gitlink-cli api GET /pm/weekly_issues \ + --query "project_id=$PROJECT_ID&start_date=$LAST_START&end_date=$LAST_END" --format json) + + # 比较输出 + echo "## 周环比分析" + echo "新增 Issue: $THIS_WEEK ↓ $LAST_WEEK" + echo "完成 Issue: $THIS_WEEK ↓ $LAST_WEEK" +} + +# 导出为文件 +export_weekly_report() { + PROJECT_ID=$(gitlink-cli repo +info --format json | jq -r '.data.project_id') + DATE=$(date +%Y-%m-%d) + + gitlink-cli api GET /pm/weekly_issues --query "project_id=$PROJECT_ID" --format json | \ + jq '.' > "weekly_report_$DATE.json" +} +``` + +## Team Collaboration + +团队协作建议: + +1. **定期分享**:每周固定时间分享周报 +2. **数据透明**:保持团队对项目进度的了解 +3. **问题讨论**:基于周报数据讨论问题和改进 +4. **成果认可**:认可和庆祝团队成就 +5. **持续改进**:基于周报分析优化工作流程 + +## Error Handling + +常见错误及解决方案: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `400` | PM 模块未开启 | 联系项目管理员开启 PM 模块 | +| `404` | 项目不存在 | 检查 project_id 是否正确 | +| `400` | 日期格式错误 | 确保日期格式为 YYYY-MM-DD | +| `403` | 权限不足 | 确认有查看该项目的权限 | +| `404` | 数据不存在 | 指定日期范围内可能没有活动数据 | + +## Report Templates + +报告模板示例: + +```markdown +# 项目周报(第{{week_number}}周) + +**时间范围**:{{start_date}} 至 {{end_date}} + +## 📊 核心指标 +- ✅ 完成 Issue:{{closed_issues}} 个 +- 🆕 新增 Issue:{{new_issues}} 个 +- 🔀 合并 PR:{{merged_prs}} 个 +- 💻 代码提交:{{total_commits}} 次 + +## 👥 团队贡献 +{{#each team_contributions}} +### {{developer}} +- 提交:{{commits_count}} 次 +- 合并 PR:{{prs_merged}} 个 +- 完成 Issue:{{issues_closed}} 个 +{{/each}} + +## 🎯 主要成果 +{{#each closed_issues}} +- {{subject}} ({{assigned_to}}) +{{/each}} + +## 🔄 进行中工作 +{{#each in_progress_issues}} +- {{subject}} ({{assigned_to}}) +{{/each}} +``` + +## References + +- [pm-kanban](pm-kanban.md) — 看板管理 +- [pm-sprint](pm-sprint.md) — Sprint 管理 +- [gitlink-pm](../SKILL.md) — 项目管理总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 +- [repo +info](../../gitlink-repo/references/repo-info.md) — 获取仓库信息 diff --git a/skills/gitlink-pm/references/pm-sprint.md b/skills/gitlink-pm/references/pm-sprint.md new file mode 100644 index 0000000..435e626 --- /dev/null +++ b/skills/gitlink-pm/references/pm-sprint.md @@ -0,0 +1,296 @@ +# PM Sprint 管理 + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **注意**:PM 功能需要项目开启 PM 模块,并通过项目 ID 访问。 + +GitLink PM Sprint 功能支持敏捷开发的迭代管理,帮助团队组织和管理特定时间段内的开发任务。 + +## 命令 + +```bash +# 查看 Sprint Issue 列表 +gitlink-cli api GET /pm/sprint_issues --query 'project_id=123' + +# 查看当前仓库的项目 ID +gitlink-cli repo +info --format json | jq '.data.project_id' + +# 组合命令:自动获取项目 ID 并查看 Sprint +PROJECT_ID=$(gitlink-cli repo +info --format json | jq -r '.data.project_id') +gitlink-cli api GET /pm/sprint_issues --query "project_id=$PROJECT_ID" + +# 查看特定 Sprint 的信息 +gitlink-cli api GET /pm/sprint_issues --query 'project_id=123&sprint_id=1' + +# 查看 Issue 标签 +gitlink-cli api GET /pm/issue_tags --query 'project_id=123' +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `project_id` | **是** | 项目 ID(通过 `repo +info` 获取) | +| `sprint_id` | 否 | Sprint ID(可选,用于查看特定 Sprint) | +| `--owner` | 否* | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否* | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 启用调试输出 | + +> *如果在 GitLink 仓库目录下执行,`--owner` 和 `--repo` 可自动推断。 + +## API + +``` +GET /api/pm/sprint_issues?project_id={project_id}&sprint_id={sprint_id} +``` + +**响应示例:** + +```json +{ + "ok": true, + "data": { + "sprint_issues": [ + { + "id": 789, + "subject": "完成用户管理模块", + "sprint_id": 1, + "sprint_name": "Sprint 1 - 基础功能", + "status": "open", + "priority": "high", + "assigned_to": "developer1", + "estimated_hours": 40, + "spent_hours": 28, + "completion_percentage": 70, + "start_date": "2026-01-01", + "end_date": "2026-01-14", + "tags": ["backend", "user-management"] + }, + { + "id": 790, + "subject": "实现权限控制", + "sprint_id": 1, + "sprint_name": "Sprint 1 - 基础功能", + "status": "in_progress", + "priority": "high", + "assigned_to": "developer2", + "estimated_hours": 32, + "spent_hours": 15, + "completion_percentage": 47, + "start_date": "2026-01-01", + "end_date": "2026-01-14", + "tags": ["backend", "security"] + } + ], + "total_count": 12 + } +} +``` + +## Workflow + +1. **Get Project ID** using `repo +info`. +2. **Execute** `gitlink-cli api GET /pm/sprint_issues --query 'project_id='`. +3. **Display** sprint issues and progress. + +> [!NOTE] +> This is a **Read Operation** — no confirmation needed. + +## Use Cases + +- **Sprint 规划**:查看和规划 Sprint 中的任务 +- **进度跟踪**:监控 Sprint 的执行进度 +- **资源分配**:合理分配团队成员到 Sprint 任务 +- **性能分析**:分析团队的开发速度和效率 + +## Sprint Lifecycle + +典型的 Sprint 生命周期: + +``` +1. Sprint 规划 + ├── 确定 Sprint 目标 + ├── 选择要处理的 Issue + └── 估算工作量 + +2. Sprint 执行 + ├── 开发团队实现功能 + ├── 每日站会同步进度 + └── 处理阻塞问题 + +3. Sprint 评审 + ├── 演示完成的功能 + ├── 收集反馈意见 + └── 确定验收结果 + +4. Sprint 回顾 + ├── 总结经验教训 + ├── 优化工作流程 + └── 制定改进计划 +``` + +## Common Operations + +Sprint 常用操作: + +### 查看 Sprint 概览 +```bash +# 查看 Sprint 统计信息 +gitlink-cli api GET /pm/sprint_issues --query 'project_id=123' --format json | \ + jq '{total: .data.total_count, + high_priority: [.data.sprint_issues[] | select(.priority=="high")] | length, + completed: [.data.sprint_issues[] | select(.status=="closed")] | length}' +``` + +### 查看 Sprint 进度 +```bash +# 计算 Sprint 完成百分比 +gitlink-cli api GET /pm/sprint_issues --query 'project_id=123' --format json | \ + jq '[.data.sprint_issues[].completion_percentage] | add / length' +``` + +### 分析工作负载 +```bash +# 按人员统计工作负载 +gitlink-cli api GET /pm/sprint_issues --query 'project_id=123' --format json | \ + jq '[.data.sprint_issues[] | {assigned_to: .assigned_to, estimated: .estimated_hours}] | + group_by(.assigned_to) | + map({developer: .[0].assigned_to, total_hours: (map(.estimated) | add)})' +``` + +## Sprint Metrics + +Sprint 关键指标: + +| 指标 | 说明 | 计算方式 | +|------|------|----------| +| **Sprint 速度** | 团队在一个 Sprint 中完成的工作量 | 完成的 Issue 数 × 复杂度权重 | +| **完成率** | Sprint 中已完成任务的百分比 | 已完成数 / 总数 × 100% | +| **剩余工作量** | Sprint 中未完成的工作量 | 未完成任务的估算小时数 | +| **工作负载** | 团队成员的工作分布 | 每人分配的估算小时数 | +| **延期风险** | 可能无法按时完成的任务 | 接近截止日期但未完成的任务 | + +## Analysis Examples + +Sprint 数据分析示例: + +```bash +# 1. 获取项目 ID +PROJECT_ID=$(gitlink-cli repo +info --format json | jq -r '.data.project_id') + +# 2. 查看 Sprint 概览 +gitlink-cli api GET /pm/sprint_issues --query "project_id=$PROJECT_ID" --format json + +# 3. 分析高优先级任务 +gitlink-cli api GET /pm/sprint_issues --query "project_id=$PROJECT_ID" --format json | \ + jq '.data.sprint_issues[] | select(.priority=="high") | {subject, status, completion_percentage}' + +# 4. 识别延期风险 +gitlink-cli api GET /pm/sprint_issues --query "project_id=$PROJECT_ID" --format json | \ + jq '.data.sprint_issues[] | + select(.status != "closed" and .end_date < (now | todate)) | + {subject, end_date, completion_percentage}' + +# 5. 计算团队效率 +gitlink-cli api GET /pm/sprint_issues --query "project_id=$PROJECT_ID" --format json | \ + jq '{total_estimated: [.data.sprint_issues[].estimated_hours] | add, + total_spent: [.data.sprint_issues[].spent_hours] | add, + efficiency: ([.data.sprint_issues[].spent_hours] | add) / + ([.data.sprint_issues[].estimated_hours] | add) * 100}' +``` + +## Sprint Planning + +Sprint 规划建议: + +1. **合理估算**:基于历史数据估算工作量 +2. **优先级排序**:优先处理高价值和高优先级任务 +3. **负载均衡**:合理分配任务给团队成员 +4. **预留缓冲**:为不可预见的问题预留时间 + +## Tips + +- Sprint 数据可以帮助团队了解开发进度 +- 定期查看 Sprint 统计可以及时发现问题 +- 结合 Issue 操作可以实现完整的任务管理 +- 使用 JSON 格式输出便于自动化分析 + +## Integration with Other Features + +与其他功能集成: + +```bash +# Sprint + Issue 操作 +# 1. 查看 Sprint 中的任务 +gitlink-cli api GET /pm/sprint_issues --query 'project_id=123' --format json + +# 2. 查看特定任务详情 +gitlink-cli issue +view --issue 789 + +# 3. 更新任务状态 +gitlink-cli issue +update --issue 789 --status_id 3 --done_ratio 80 +``` + +## Best Practices + +Sprint 管理最佳实践: + +1. **时间盒固定**:Sprint 时长通常为 2-4 周 +2. **目标明确**:每个 Sprint 应有明确的目标 +3. **任务可衡量**:Sprint 任务应该是可衡量和可完成的 +4. **定期回顾**:每个 Sprint 结束后进行回顾总结 +5. **持续改进**:基于回顾结果优化工作流程 + +## Error Handling + +常见错误及解决方案: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `400` | PM 模块未开启 | 联系项目管理员开启 PM 模块 | +| `404` | 项目不存在 | 检查 project_id 是否正确 | +| `404` | Sprint 不存在 | 检查 sprint_id 是否正确 | +| `403` | 权限不足 | 确认有查看该项目的权限 | + +## Advanced Usage + +高级用法示例: + +```bash +# 生成 Sprint 报告 +generate_sprint_report() { + PROJECT_ID=$(gitlink-cli repo +info --format json | jq -r '.data.project_id') + + echo "# Sprint Report" + echo "## Overview" + gitlink-cli api GET /pm/sprint_issues --query "project_id=$PROJECT_ID" --format json | \ + jq -r '"Total: \(.data.total_count) issues"' + + echo "## Priority Distribution" + gitlink-cli api GET /pm/sprint_issues --query "project_id=$PROJECT_ID" --format json | \ + jq '.data.sprint_issues | group_by(.priority) | map({priority: .[0].priority, count: length})' + + echo "## Team Workload" + gitlink-cli api GET /pm/sprint_issues --query "project_id=$PROJECT_ID" --format json | \ + jq '[.data.sprint_issues[] | {assigned_to: .assigned_to, hours: .estimated_hours}] | + group_by(.assigned_to) | + map({developer: .[0].assigned_to, total_hours: (map(.hours) | add)})' +} +``` + +## Team Collaboration + +团队协作建议: + +1. **Sprint 规划会议**:全团队参与 Sprint 规划 +2. **每日站会**:简短同步进度和问题 +3. **Sprint 评审**:演示和验收完成的功能 +4. **Sprint 回顾**:总结经验,持续改进 + +## References + +- [pm-kanban](pm-kanban.md) — 看板管理 +- [pm-report](pm-report.md) — 周报生成 +- [gitlink-pm](../SKILL.md) — 项目管理总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 +- [repo +info](../../gitlink-repo/references/repo-info.md) — 获取仓库信息 diff --git a/skills/gitlink-webhook/SKILL.md b/skills/gitlink-webhook/SKILL.md new file mode 100644 index 0000000..d75035f --- /dev/null +++ b/skills/gitlink-webhook/SKILL.md @@ -0,0 +1,233 @@ +--- +name: gitlink-webhook +version: 1.0.0 +description: "Webhook 管理:创建、查看、更新、删除、测试 Webhook,配置自动化触发器。当用户需要配置 GitLink 仓库的 Webhook 自动化通知时触发。" +metadata: + requires: + bins: ["gitlink-cli"] + cliHelp: "gitlink-cli webhook --help" +--- + +# gitlink-webhook(Webhook 操作) + +**CRITICAL — 开始前必须先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md),其中包含认证、权限处理和 API 注意事项。** +**CRITICAL — 所有 Shortcuts 在执行写入/删除操作前,务必先确认用户意图。** +**CRITICAL — GitLink 操作只能用 `gitlink-cli`。禁止用 `gh`(GitHub CLI)操作 GitLink 资源。`gh` 仅适用于 GitHub 平台。** + +> **前置条件:** 先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md) 了解认证和全局参数。 + +## Shortcuts + +| Shortcut | 说明 | 需要认证 | +|----------|------|----------| +| `webhook +list` | 列出仓库的所有 Webhook | 是 | +| `webhook +create` | 创建新 Webhook | 是 | +| `webhook +update` | 更新 Webhook 配置 | 是 | +| `webhook +delete` | 删除 Webhook | 是 | +| `webhook +test` | 测试 Webhook 推送(发送 ping 事件) | 是 | +| `webhook +info` | 查看 Webhook 详情 | 是 | +| `webhook +events` | 列出所有支持的事件类型 | 否 | + +## 支持的事件类型 + +| 事件类型 | 说明 | 触发时机 | +|----------|------|----------| +| `push` | 代码推送事件 | 向仓库推送代码时 | +| `pull_request` | Pull 请求事件 | 创建、更新、关闭 PR 时 | +| `issue` | Issue 事件 | 创建、更新、关闭 Issue 时 | +| `issue_assign` | Issue 指派事件 | Issue 被指派给用户时 | +| `issue_comment` | Issue 评论事件 | Issue 添加评论时 | +| `pull_request_assign` | PR 指派事件 | PR 被指派给审查者时 | +| `pull_request_comment` | PR 评论事件 | PR 添加评论时 | +| `merge_request` | 合并请求事件 | PR 被合并时 | +| `repository` | 仓库事件 | 仓库设置变更时 | +| `branch` | 分支事件 | 创建或删除分支时 | +| `tag` | 标签事件 | 创建或删除标签时 | + +## 使用示例 + +### 基本操作 + +```bash +# 列出仓库的所有 Webhook +gitlink-cli webhook +list --owner myuser --repo myrepo + +# 查看 Webhook 详情 +gitlink-cli webhook +info --owner myuser --repo myrepo --id 123 + +# 列出所有支持的事件类型 +gitlink-cli webhook +events +``` + +### 创建 Webhook + +```bash +# 创建基本的 Webhook(仅监听 push 事件) +gitlink-cli webhook +create --owner myuser --repo myrepo --url https://example.com/webhook + +# 创建多事件 Webhook +gitlink-cli webhook +create --owner myuser --repo myrepo --url https://example.com/webhook --events push,pull_request,issue + +# 创建带密钥的 Webhook +gitlink-cli webhook +create --owner myuser --repo myrepo --url https://example.com/webhook --secret my-secret-key --events push + +# 创建带描述的 Webhook +gitlink-cli webhook +create --owner myuser --repo myrepo --url https://example.com/webhook --description "CI/CD automation" +``` + +### 更新 Webhook + +```bash +# 更新 Webhook URL +gitlink-cli webhook +update --owner myuser --repo myrepo --id 123 --url https://new-url.com/webhook + +# 更新监听事件 +gitlink-cli webhook +update --owner myuser --repo myrepo --id 123 --events push,pull_request + +# 激活/停用 Webhook +gitlink-cli webhook +update --owner myuser --repo myrepo --id 123 --active false + +# 更新多个属性 +gitlink-cli webhook +update --owner myuser --repo myrepo --id 123 --url https://new-url.com/webhook --events push,pull_request --secret new-secret +``` + +### 测试和删除 + +```bash +# 测试 Webhook(发送 ping 事件) +gitlink-cli webhook +test --owner myuser --repo myrepo --id 123 + +# 测试特定事件类型 +gitlink-cli webhook +test --owner myuser --repo myrepo --id 123 --event push + +# 删除 Webhook +gitlink-cli webhook +delete --owner myuser --repo myrepo --id 123 +``` + +## 典型使用场景 + +### 场景1: 配置 CI/CD 自动化 + +```bash +# 为 CI/CD 系统创建 Webhook +gitlink-cli webhook +create \ + --owner myuser --repo myrepo \ + --url https://ci.example.com/gitlink/webhook \ + --events push,pull_request \ + --secret ci-secret-key \ + --description "Trigger CI/CD pipeline" +``` + +### 场景2: 配置 Issue 通知 + +```bash +# 创建 Issue 通知 Webhook +gitlink-cli webhook +create \ + --owner myuser --repo myrepo \ + --url https://notification.example.com/issues \ + --events issue,issue_comment,issue_assign \ + --description "Issue notifications" +``` + +### 场景3: 配置 PR 审查通知 + +```bash +# 创建 PR 审查 Webhook +gitlink-cli webhook +create \ + --owner myuser --repo myrepo \ + --url https://review.example.com/prs \ + --events pull_request,pull_request_comment,pull_request_assign \ + --description "PR review notifications" +``` + +## 错误处理 + +### 常见错误 + +#### 1. 认证错误 +```bash +Error: [401] Authentication failed +``` +**解决方案**: 运行 `gitlink-cli auth login` 重新认证 + +#### 2. 权限不足 +```bash +Error: [403] You are not authorized to manage webhooks +``` +**解决方案**: 确认您对仓库有管理员权限 + +#### 3. 无效的事件类型 +```bash +Error: no valid events specified +``` +**解决方案**: 使用 `gitlink-cli webhook +events` 查看支持的事件类型 + +#### 4. Webhook 不存在 +```bash +Error: [404] Webhook not found +``` +**解决方案**: 使用 `gitlink-cli webhook +list` 确认 Webhook ID 是否正确 + +## AI Agent 使用指南 + +### 检查现有 Webhook +```bash +# 1. 列出所有 Webhook +gitlink-cli webhook +list --owner $OWNER --repo $REPO --format json + +# 2. 检查是否有特定类型的 Webhook +gitlink-cli webhook +list --owner $OWNER --repo $REPO --format json | jq '.data.webhooks[] | select(.hook_url | contains("ci-system"))' +``` + +### 创建 Webhook 的最佳实践 +```bash +# 1. 先查看支持的事件 +gitlink-cli webhook +events + +# 2. 创建 Webhook 并验证 +gitlink-cli webhook +create --owner $OWNER --repo $REPO --url $URL --events $EVENTS + +# 3. 测试 Webhook 是否正常工作 +gitlink-cli webhook +test --owner $OWNER --repo $REPO --id $WEBHOOK_ID +``` + +### 安全建议 +- **使用密钥**: 为 Webhook 设置密钥以验证请求来源 +- **HTTPS**: 始终使用 HTTPS URL 作为 Webhook 回调地址 +- **最小权限**: 只监听必要的事件类型 +- **定期轮换**: 定期更新 Webhook 密钥 + +## 参考文档 + +- [`webhook-list.md`](references/webhook-list.md) - 列出 Webhook 详细说明 +- [`webhook-create.md`](references/webhook-create.md) - 创建 Webhook 详细说明 +- [`webhook-update.md`](references/webhook-update.md) - 更新 Webhook 详细说明 +- [`webhook-delete.md`](references/webhook-delete.md) - 删除 Webhook 详细说明 +- [`webhook-test.md`](references/webhook-test.md) - 测试 Webhook 详细说明 +- [`webhook-info.md`](references/webhook-info.md) - 查看 Webhook 详细说明 +- [`examples/webhook-workflow.md`](examples/webhook-workflow.md) - 完整工作流示例 + +## 注意事项 + +1. **API 限制**: GitLink 对 Webhook 数量有限制,通常每个仓库不超过 20 个 +2. **URL 要求**: Webhook URL 必须是公网可访问的 HTTPS 地址 +3. **超时设置**: Webhook 请求超时时间为 10 秒 +4. **重试机制**: GitLink 会在失败时重试 3 次,间隔分别为 1s、5s、10s +5. **事件顺序**: 同一事件的多个 Webhook 按创建顺序依次触发 +6. **测试限制**: 测试 Webhook 不会触发实际的业务逻辑,仅验证连通性 + +## 故障排除 + +### Webhook 未触发 +1. 检查 Webhook 是否激活:`gitlink-cli webhook +info --id --active true` +2. 验证事件类型是否正确:`gitlink-cli webhook +info --id ` +3. 测试 Webhook 连通性:`gitlink-cli webhook +test --id ` + +### Webhook 响应异常 +1. 检查回调服务器是否正常运行 +2. 验证 Webhook URL 是否可访问 +3. 查看 GitLink 服务器日志确认请求是否发送 + +### 权限问题 +1. 确认当前用户是仓库管理员或所有者 +2. 检查 Token 是否有足够权限:`gitlink-cli auth status` diff --git a/skills/gitlink-webhook/examples/webhook-workflow.md b/skills/gitlink-webhook/examples/webhook-workflow.md new file mode 100644 index 0000000..bcb1b61 --- /dev/null +++ b/skills/gitlink-webhook/examples/webhook-workflow.md @@ -0,0 +1,694 @@ +# Webhook 完整工作流示例 + +本文档提供了 GitLink Webhook 的完整使用场景和最佳实践示例。 + +## 目录 + +- [场景1: CI/CD 自动化](#场景1-cicd-自动化) +- [场景2: Issue 和 PR 通知](#场景2-issue-和-pr-通知) +- [场景3: 多环境部署](#场景3-多环境部署) +- [场景4: Webhook 迁移](#场景4-webhook-迁移) +- [场景5: 故障排查](#场景5-故障排查) +- [场景6: 安全最佳实践](#场景6-安全最佳实践) + +--- + +## 场景1: CI/CD 自动化 + +### 目标 +为 Jenkins CI/CD 系统配置 Webhook,实现代码推送时自动触发构建。 + +### 完整流程 + +```bash +#!/bin/bash +# cicd-webhook-setup.sh + +PROJECT_OWNER="mycompany" +PROJECT_REPO="main-app" +JENKINS_URL="https://jenkins.example.com/gitlink-webhook" +WEBHOOK_SECRET="jenkins-secret-key-2024" + +echo "=== Setting up CI/CD Webhook for $PROJECT_OWNER/$PROJECT_REPO ===" + +# 1. 检查是否已存在 CI/CD Webhook +echo "1. Checking existing webhooks..." +existing=$(gitlink-cli webhook +list \ + --owner $PROJECT_OWNER \ + --repo $PROJECT_REPO \ + --format json | \ + jq -r ".data.webhooks[] | select(.hook_url | contains(\"jenkins\")) | .id") + +if [ -n "$existing" ]; then + echo "Found existing CI/CD webhook: $existing" + read -p "Delete existing webhook? (y/n) " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + gitlink-cli webhook +delete --owner $PROJECT_OWNER --repo $PROJECT_REPO --id $existing + echo "Existing webhook deleted" + else + echo "Aborting setup" + exit 1 + fi +fi + +# 2. 创建新的 Webhook +echo "2. Creating new CI/CD webhook..." +WEBHOOK_INFO=$(gitlink-cli webhook +create \ + --owner $PROJECT_OWNER \ + --repo $PROJECT_REPO \ + --url "$JENKINS_URL" \ + --events push,pull_request \ + --secret "$WEBHOOK_SECRET" \ + --description "Jenkins CI/CD automation" \ + --format json) + +if [ $? -eq 0 ]; then + WEBHOOK_ID=$(echo $WEBHOOK_INFO | jq -r '.data.id') + echo "✓ Webhook created successfully: $WEBHOOK_ID" +else + echo "✗ Failed to create webhook" + exit 1 +fi + +# 3. 测试 Webhook +echo "3. Testing webhook..." +if gitlink-cli webhook +test --owner $PROJECT_OWNER --repo $PROJECT_REPO --id $WEBHOOK_ID; then + echo "✓ Webhook test successful" +else + echo "⚠ Webhook test failed, please check Jenkins server" + read -p "Continue anyway? (y/n) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + gitlink-cli webhook +delete --id $WEBHOOK_ID + echo "Webhook deleted due to test failure" + exit 1 + fi +fi + +# 4. 验证配置 +echo "4. Verifying configuration..." +gitlink-cli webhook +info --owner $PROJECT_OWNER --repo $PROJECT_REPO --id $WEBHOOK_ID + +echo "=== CI/CD Webhook Setup Complete ===" +echo "Webhook ID: $WEBHOOK_ID" +echo "Jenkins URL: $JENKINS_URL" +echo "Events: push, pull_request" +``` + +### 使用说明 + +```bash +# 1. 设置脚本权限 +chmod +x cicd-webhook-setup.sh + +# 2. 运行脚本 +./cicd-webhook-setup.sh + +# 3. 验证 Webhook 是否正常工作 +# 在 Jenkins 中检查是否收到 Webhook 事件 +``` + +--- + +## 场景2: Issue 和 PR 通知 + +### 目标 +配置 Slack 通知,在 Issue 和 PR 活动时发送消息到团队频道。 + +### 完整流程 + +```bash +#!/bin/bash +# notification-webhook-setup.sh + +PROJECT_OWNER="myteam" +PROJECT_REPO="project-x" +SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" + +echo "=== Setting up Notification Webhooks ===" + +# Issue 通知 Webhook +echo "1. Creating Issue notification webhook..." +ISSUE_WEBHOOK_ID=$(gitlink-cli webhook +create \ + --owner $PROJECT_OWNER \ + --repo $PROJECT_REPO \ + --url "$SLACK_WEBHOOK_URL" \ + --events issue,issue_comment,issue_assign \ + --description "Issue notifications to #dev-team" \ + --format json | jq -r '.data.id') + +echo "✓ Issue webhook created: $ISSUE_WEBHOOK_ID" + +# PR 通知 Webhook +echo "2. Creating PR notification webhook..." +PR_WEBHOOK_ID=$(gitlink-cli webhook +create \ + --owner $PROJECT_OWNER \ + --repo $PROJECT_REPO \ + --url "$SLACK_WEBHOOK_URL" \ + --events pull_request,pull_request_comment,pull_request_assign \ + --description "PR notifications to #dev-team" \ + --format json | jq -r '.data.id') + +echo "✓ PR webhook created: $PR_WEBHOOK_ID" + +# 测试两个 Webhook +echo "3. Testing webhooks..." +gitlink-cli webhook +test --id $ISSUE_WEBHOOK_ID --event issue +gitlink-cli webhook +test --id $PR_WEBHOOK_ID --event pull_request + +# 查看配置 +echo "4. Webhook summary:" +echo "Issue Webhook: $ISSUE_WEBHOOK_ID" +gitlink-cli webhook +info --id $ISSUE_WEBHOOK_ID +echo +echo "PR Webhook: $PR_WEBHOOK_ID" +gitlink-cli webhook +info --id $PR_WEBHOOK_ID + +echo "=== Notification Setup Complete ===" +``` + +### 多团队通知 + +```bash +#!/bin/bash +# multi-team-notifications.sh + +# 为不同团队配置不同的通知 +declare -A TEAM_WEBHOOKS=( + ["dev-team"]="https://hooks.slack.com/services/DEV/TEAM/WEBHOOK" + ["ops-team"]="https://hooks.slack.com/services/OPS/TEAM/WEBHOOK" + ["security-team"]="https://hooks.slack.com/services/SECURITY/TEAM/WEBHOOK" +) + +for team in "${!TEAM_WEBHOOKS[@]}"; do + webhook_url="${TEAM_WEBHOOKS[$team]}" + + echo "Setting up webhook for $team..." + + gitlink-cli webhook +create \ + --owner $PROJECT_OWNER \ + --repo $PROJECT_REPO \ + --url "$webhook_url" \ + --events push,pull_request,issue \ + --description "Notifications for #$team" +done +``` + +--- + +## 场景3: 多环境部署 + +### 目标 +为不同环境(开发、测试、生产)配置独立的 Webhook。 + +### 完整流程 + +```bash +#!/bin/bash +# multi-env-webhook-setup.sh + +PROJECT_OWNER="mycompany" +PROJECT_REPO="main-app" + +# 环境配置 +declare -A ENVIRONMENTS=( + ["development"]="https://ci-dev.example.com/webhook" + ["testing"]="https://ci-test.example.com/webhook" + ["production"]="https:ci-prod.example.com/webhook" +) + +# 为每个环境创建 Webhook +for env in "${!ENVIRONMENTS[@]}"; do + webhook_url="${ENVIRONMENTS[$env]}" + secret="${env}-secret-$(date +%Y%m%d)" + + echo "=== Setting up $env environment webhook ===" + + # 创建 Webhook + webhook_id=$(gitlink-cli webhook +create \ + --owner $PROJECT_OWNER \ + --repo $PROJECT_REPO \ + --url "$webhook_url" \ + --events push,pull_request \ + --secret "$secret" \ + --description "$env environment CI/CD" \ + --format json | jq -r '.data.id') + + echo "✓ $env webhook created: $webhook_id" + + # 根据环境设置不同的激活状态 + if [ "$env" = "production" ]; then + # 生产环境默认激活 + echo "Production webhook is active" + else + # 其他环境暂时停用,需要时手动激活 + gitlink-cli webhook +update --id $webhook_id --active false + echo "$env webhook created but inactive (activate manually when needed)" + fi + + echo +done + +echo "=== Multi-environment setup complete ===" +echo "Review created webhooks:" +gitlink-cli webhook +list +``` + +### 环境切换 + +```bash +#!/bin/bash +# switch-active-environment.sh + +# 切换激活的环境 +TARGET_ENV=$1 + +if [ -z "$TARGET_ENV" ]; then + echo "Usage: $0 " + echo "Available environments: development, testing, production" + exit 1 +fi + +echo "=== Switching to $TARGET_ENV environment ===" + +# 停用所有环境 Webhook +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + webhook_url=$(gitlink-cli webhook +info --id $id --format json | jq -r '.data.hook_url') + + if [[ "$webhook_url" == *"ci-"* ]]; then + echo "Deactivating webhook $id..." + gitlink-cli webhook +update --id $id --active false + fi +done + +# 激活目标环境 Webhook +target_webhook_id=$(gitlink-cli webhook +list --format json | \ + jq -r ".data.webhooks[] | select(.hook_url | contains(\"$TARGET_ENV\")) | .id") + +if [ -n "$target_webhook_id" ]; then + echo "Activating $TARGET_ENV webhook: $target_webhook_id" + gitlink-cli webhook +update --id $target_webhook_id --active true + + # 测试激活的 Webhook + gitlink-cli webhook +test --id $target_webhook_id + + echo "✓ Switched to $TARGET_ENV environment" +else + echo "✗ No webhook found for $TARGET_ENV environment" + exit 1 +fi +``` + +--- + +## 场景4: Webhook 迁移 + +### 目标 +将 Webhook 从旧服务器迁移到新服务器。 + +### 完整流程 + +```bash +#!/bin/bash +# webhook-migration.sh + +OLD_SERVER="old-ci.example.com" +NEW_SERVER="new-ci.example.com" +PROJECT_OWNER="mycompany" +PROJECT_REPO="main-app" + +echo "=== Webhook Migration: $OLD_SERVER → $NEW_SERVER ===" + +# 1. 查找需要迁移的 Webhook +echo "1. Finding webhooks to migrate..." +webhooks_to_migrate=$(gitlink-cli webhook +list \ + --owner $PROJECT_OWNER \ + --repo $PROJECT_REPO \ + --format json | \ + jq -r ".data.webhooks[] | select(.hook_url | contains(\"$OLD_SERVER\"))") + +webhook_count=$(echo "$webhooks_to_migrate" | jq -r '. | length') + +if [ "$webhook_count" -eq 0 ]; then + echo "No webhooks found for $OLD_SERVER" + exit 0 +fi + +echo "Found $webhook_count webhook(s) to migrate" + +# 2. 为每个 Webhook 创建迁移记录 +echo "$webhooks_to_migrate" | jq -c '.[]' | while read -r webhook; do + old_id=$(echo $webhook | jq -r '.id') + old_url=$(echo $webhook | jq -r '.hook_url') + events=$(echo $webhook | jq -r '.events | join(",")') + description=$(echo $webhook | jq -r '.description') + + # 生成新 URL + new_url=$(echo $old_url | sed "s/$OLD_SERVER/$NEW_SERVER/g") + + echo "=== Migrating webhook $old_id ===" + echo "Old URL: $old_url" + echo "New URL: $new_url" + echo "Events: $events" + + # 创建新 Webhook + echo "Creating new webhook..." + new_id=$(gitlink-cli webhook +create \ + --owner $PROJECT_OWNER \ + --repo $PROJECT_REPO \ + --url "$new_url" \ + --events "$events" \ + --description "$description (migrated)" \ + --format json | jq -r '.data.id') + + if [ $? -eq 0 ]; then + echo "✓ New webhook created: $new_id" + + # 测试新 Webhook + echo "Testing new webhook..." + if gitlink-cli webhook +test --id $new_id; then + echo "✓ New webhook test successful" + + # 备份旧 Webhook 配置 + echo "$webhook" > "webhook_backup_${old_id}.json" + + # 删除旧 Webhook + echo "Deleting old webhook: $old_id" + gitlink-cli webhook +delete --id $old_id + + echo "✓ Migration complete for webhook $old_id" + else + echo "⚠ New webhook test failed, keeping old webhook" + gitlink-cli webhook +delete --id $new_id + fi + else + echo "✗ Failed to create new webhook" + fi + + echo +done + +echo "=== Migration Complete ===" +echo "Current webhooks:" +gitlink-cli webhook +list --owner $PROJECT_OWNER --repo $PROJECT_REPO +``` + +### 回滚迁移 + +```bash +#!/bin/bash +# rollback-migration.sh + +echo "=== Webhook Migration Rollback ===" + +# 从备份文件恢复 Webhook +for backup_file in webhook_backup_*.json; do + old_id=$(echo $backup_file | sed 's/webhook_backup_\([0-9]*\)\.json/\1/') + + echo "Restoring webhook: $old_id" + + # 读取备份配置 + webhook_config=$(cat "$backup_file") + old_url=$(echo $webhook_config | jq -r '.hook_url') + events=$(echo $webhook_config | jq -r '.events | join(",")') + description=$(echo $webhook_config | jq -r '.description') + + # 重新创建 Webhook + restored_id=$(gitlink-cli webhook +create \ + --url "$old_url" \ + --events "$events" \ + --description "$description (restored)" \ + --format json | jq -r '.data.id') + + echo "✓ Webhook restored: $restored_id" +done + +echo "=== Rollback Complete ===" +``` + +--- + +## 场景5: 故障排查 + +### 目标 +诊断和修复 Webhook 问题。 + +### 故障排查脚本 + +```bash +#!/bin/bash +# webhook-troubleshooting.sh + +WEBHOOK_ID=$1 + +if [ -z "$WEBHOOK_ID" ]; then + echo "Usage: $0 " + exit 1 +fi + +echo "=== Webhook Troubleshooting for ID: $WEBHOOK_ID ===" +echo + +# 1. 检查 Webhook 是否存在 +echo "1. Checking webhook existence..." +if ! gitlink-cli webhook +info --id $WEBHOOK_ID >/dev/null 2>&1; then + echo "✗ Webhook not found" + echo "Available webhooks:" + gitlink-cli webhook +list + exit 1 +fi +echo "✓ Webhook exists" + +# 2. 获取 Webhook 详细信息 +echo "2. Webhook configuration:" +webhook_info=$(gitlink-cli webhook +info --id $WEBHOOK_ID --format json) +echo "$webhook_info" | jq -r '.data | { + URL: .hook_url, + Active: .is_active, + Events: .events | join(", "), + "Last Delivery": .last_delivery.timestamp, + "Success Rate": (.delivery_statistics.success_rate // "N/A") +}' + +# 3. 检查 Webhook 是否激活 +is_active=$(echo $webhook_info | jq -r '.data.is_active') +if [ "$is_active" != "true" ]; then + echo "⚠ Webhook is not active" + read -p "Activate webhook now? (y/n) " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + gitlink-cli webhook +update --id $WEBHOOK_ID --active true + echo "✓ Webhook activated" + fi +fi + +# 4. 测试网络连通性 +echo "3. Testing network connectivity..." +webhook_url=$(echo $webhook_info | jq -r '.data.hook_url') +if curl -s -o /dev/null -w "%{http_code}" "$webhook_url" | grep -q "200\|301\|302"; then + echo "✓ URL is accessible (HTTP $(curl -s -o /dev/null -w "%{http_code}" "$webhook_url"))" +else + echo "✗ URL is not accessible" + echo "Testing with curl:" + curl -v "$webhook_url" 2>&1 | head -20 +fi + +# 5. 测试 Webhook +echo "4. Testing webhook delivery..." +if gitlink-cli webhook +test --id $WEBHOOK_ID; then + echo "✓ Webhook test successful" +else + echo "✗ Webhook test failed" + echo "Common issues:" + echo " - URL is not reachable" + echo " - Server is not responding" + echo " - Firewall blocking requests" + echo " - SSL certificate issues" +fi + +# 6. 检查成功率 +echo "5. Checking delivery statistics..." +success_rate=$(echo $webhook_info | jq -r '.data.delivery_statistics.success_rate // "N/A"') +if [ "$success_rate" != "N/A" ]; then + if (( $(echo "$success_rate < 90" | bc -l) )); then + echo "⚠ Low success rate: $success_rate%" + echo "Recommendation: Check webhook server logs for errors" + else + echo "✓ Good success rate: $success_rate%" + fi +else + echo "No delivery statistics available (webhook may be new)" +fi + +# 7. 诊断建议 +echo "6. Troubleshooting recommendations:" +echo " - Check webhook server logs: tail -f /var/log/webhook-server.log" +echo " - Test webhook URL manually: curl -X POST $webhook_url" +echo " - Verify SSL certificate: openssl s_client -connect $(echo $webhook_url | sed 's/https:\/\///' | sed 's/:443//')" + +echo "=== Troubleshooting Complete ===" +``` + +### 常见问题解决 + +```bash +#!/bin/bash +# common-webhook-fixes.sh + +# 问题1: Webhook 未触发 +fix_inactive_webhook() { + WEBHOOK_ID=$1 + echo "Fixing inactive webhook: $WEBHOOK_ID" + gitlink-cli webhook +update --id $WEBHOOK_ID --active true + gitlink-cli webhook +test --id $WEBHOOK_ID +} + +# 问题2: URL 配置错误 +fix_webhook_url() { + WEBHOOK_ID=$1 + CORRECT_URL=$2 + echo "Fixing webhook URL for: $WEBHOOK_ID" + gitlink-cli webhook +update --id $WEBHOOK_ID --url "$CORRECT_URL" + gitlink-cli webhook +test --id $WEBHOOK_ID +} + +# 问题3: 事件配置不完整 +fix_webhook_events() { + WEBHOOK_ID=$1 + DESIRED_EVENTS=$2 + echo "Updating webhook events for: $WEBHOOK_ID" + gitlink-cli webhook +update --id $WEBHOOK_ID --events "$DESIRED_EVENTS" +} + +# 问题4: 密钥过期 +rotate_webhook_secret() { + WEBHOOK_ID=$1 + NEW_SECRET=$(openssl rand -hex 32) + echo "Rotating secret for webhook: $WEBHOOK_ID" + gitlink-cli webhook +update --id $WEBHOOK_ID --secret "$NEW_SECRET" + echo "New secret: $NEW_SECRET" + echo "Please update the receiving server with the new secret" +} +``` + +--- + +## 场景6: 安全最佳实践 + +### 目标 +确保 Webhook 配置符合安全最佳实践。 + +### 安全配置检查 + +```bash +#!/bin/bash +# webhook-security-audit.sh + +echo "=== Webhook Security Audit ===" + +# 1. 检查所有 Webhook 是否使用 HTTPS +echo "1. Checking HTTPS usage..." +insecure_count=0 +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + url=$(gitlink-cli webhook +info --id $id --format json | jq -r '.data.hook_url') + if [[ ! $url =~ ^https:// ]]; then + echo "⚠ Insecure URL found: $url (webhook $id)" + insecure_count=$((insecure_count + 1)) + fi +done +if [ $insecure_count -eq 0 ]; then + echo "✓ All webhooks use HTTPS" +else + echo "✗ Found $insecure_count webhook(s) using non-HTTPS URLs" +fi + +# 2. 检查是否设置了密钥 +echo "2. Checking secret usage..." +no_secret_count=0 +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + has_secret=$(gitlink-cli webhook +info --id $id --format json | jq -r '.data.has_secret // false') + if [ "$has_secret" = "false" ]; then + echo "⚠ Webhook without secret: $id" + no_secret_count=$((no_secret_count + 1)) + fi +done +if [ $no_secret_count -eq 0 ]; then + echo "✓ All webhooks have secrets configured" +else + echo "⚠ $no_secret_count webhook(s) without secrets" +fi + +# 3. 检查 Webhook 数量 +echo "3. Checking webhook count..." +webhook_count=$(gitlink-cli webhook +list --format json | jq -r '.data.total_count') +if [ $webhook_count -gt 15 ]; then + echo "⚠ High webhook count: $webhook_count (consider cleanup)" +else + echo "✓ Reasonable webhook count: $webhook_count" +fi + +# 4. 检查不活跃的 Webhook +echo "4. Checking inactive webhooks..." +inactive_count=$(gitlink-cli webhook +list --format json | jq -r '[.data.webhooks[] | select(.is_active == false)] | length') +if [ $inactive_count -gt 0 ]; then + echo "⚠ Found $inactive_count inactive webhook(s)" + echo "Consider removing inactive webhooks:" + gitlink-cli webhook +list --format json | jq -r '.data.webhooks[] | select(.is_active == false) | "\(.id): \(.hook_url)"' +else + echo "✓ All webhooks are active" +fi + +echo "=== Security Audit Complete ===" +``` + +### 安全加固脚本 + +```bash +#!/bin/bash +# webhook-security-hardening.sh + +echo "=== Webhook Security Hardening ===" + +# 1. 为所有 Webhook 添加密钥 +echo "1. Adding secrets to webhooks without them..." +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + has_secret=$(gitlink-cli webhook +info --id $id --format json | jq -r '.data.has_secret // false') + if [ "$has_secret" = "false" ]; then + echo "Adding secret to webhook $id..." + new_secret=$(openssl rand -hex 32) + gitlink-cli webhook +update --id $id --secret "$new_secret" + echo "✓ Secret added. Save this secret: $new_secret" + fi +done + +# 2. 停用不必要的 Webhook +echo "2. Reviewing webhooks for necessity..." +gitlink-cli webhook +list --format json | jq -r '.data.webhooks[] | "\(.id): \(.description"' | while read -r webhook; do + echo "Webhook: $webhook" + read -p "Is this webhook still needed? (y/n) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + webhook_id=$(echo $webhook | cut -d':' -f1) + gitlink-cli webhook +delete --id $webhook_id + echo "✓ Webhook deleted" + fi +done + +echo "=== Security Hardening Complete ===" +``` + +--- + +## 总结 + +这些工作流示例涵盖了 Webhook 管理的主要场景: + +1. **CI/CD 自动化** - 配置持续集成/部署 +2. **通知系统** - Issue 和 PR 消息通知 +3. **多环境部署** - 为不同环境配置独立 Webhook +4. **Webhook 迁移** - 安全地迁移 Webhook 配置 +5. **故障排查** - 诊断和修复 Webhook 问题 +6. **安全最佳实践** - 确保 Webhook 配置安全 + +使用这些示例作为起点,根据您的具体需求进行调整和扩展。 diff --git a/skills/gitlink-webhook/references/webhook-create.md b/skills/gitlink-webhook/references/webhook-create.md new file mode 100644 index 0000000..2fb8951 --- /dev/null +++ b/skills/gitlink-webhook/references/webhook-create.md @@ -0,0 +1,274 @@ +# gitlink-cli webhook +create + +创建新的 Webhook,用于自动化通知和集成。 + +## 命令格式 + +```bash +gitlink-cli webhook +create \ + --owner OWNER \ + --repo REPO \ + --url URL \ + [--events EVENTS] \ + [--active ACTIVE] \ + [--content_type CONTENT_TYPE] \ + [--secret SECRET] \ + [--description DESCRIPTION] +``` + +## 参数说明 + +| 参数 | 短参数 | 说明 | 是否必须 | 默认值 | +|------|--------|------|----------|--------| +| `--owner` | `-o` | 仓库所有者 | 否 | 自动从 git remote 解析 | +| `--repo` | `-r` | 仓库名称 | 否 | 自动从 git remote 解析 | +| `--url` | `-u` | Webhook 回调 URL | **是** | - | +| `--events` | `-e` | 触发事件(逗号分隔) | 否 | `push` | +| `--active` | - | 是否激活 | 否 | `true` | +| `--content_type` | - | 内容类型 | 否 | `json` | +| `--secret` | - | HMAC 验证密钥 | 否 | 空 | +| `--description` | `-d` | Webhook 描述 | 否 | 空 | + +### 事件类型 +支持的事件类型(多个事件用逗号分隔): +- `push` - 代码推送 +- `pull_request` - Pull 请求 +- `issue` - Issue 事件 +- `issue_assign` - Issue 指派 +- `issue_comment` - Issue 评论 +- `pull_request_assign` - PR 指派 +- `pull_request_comment` - PR 评论 +- `merge_request` - 合并请求 +- `repository` - 仓库事件 +- `branch` - 分支事件 +- `tag` - 标签事件 + +## 返回值 + +### 成功返回 +```json +{ + "ok": true, + "data": { + "id": "456", + "hook_url": "https://example.com/webhook", + "events": ["push", "pull_request"], + "is_active": true, + "content_type": "json", + "description": "CI/CD webhook", + "created_at": "2024-01-01T00:00:00Z", + "project": { + "owner": "myuser", + "repo": "myrepo" + } + }, + "meta": { + "identity": "user:myuser" + } +} +``` + +### 错误返回 +```json +{ + "ok": false, + "error": { + "code": 400, + "message": "Invalid webhook URL", + "suggestion": "Please provide a valid HTTPS URL" + } +} +``` + +## 使用示例 + +### 基本 Webhook +```bash +# 创建最简单的 Webhook(仅监听 push 事件) +gitlink-cli webhook +create --owner myuser --repo myrepo --url https://example.com/webhook + +# 在 git 仓库目录中创建(自动解析 owner/repo) +gitlink-cli webhook +create --url https://example.com/webhook +``` + +### 多事件 Webhook +```bash +# 监听多个事件 +gitlink-cli webhook +create \ + --owner myuser --repo myrepo \ + --url https://ci.example.com/webhook \ + --events push,pull_request,issue + +# 监听所有 PR 相关事件 +gitlink-cli webhook +create \ + --url https://review.example.com/webhook \ + --events pull_request,pull_request_assign,pull_request_comment +``` + +### 带密钥的 Webhook +```bash +# 创建带 HMAC 验证密钥的 Webhook +gitlink-cli webhook +create \ + --url https://ci.example.com/webhook \ + --events push \ + --secret my-secret-key-12345 + +# CI/CD 系统的 Webhook(推荐) +gitlink-cli webhook +create \ + --url https://jenkins.example.com/gitlink-webhook \ + --events push,pull_request \ + --secret jenkins-webhook-secret \ + --description "Jenkins CI trigger" +``` + +### 带描述的 Webhook +```bash +# 创建带描述的 Webhook +gitlink-cli webhook +create \ + --url https://notification.example.com/webhook \ + --events issue,issue_comment \ + --description "Issue notifications to Slack" +``` + +### 不激活的 Webhook +```bash +# 创建 Webhook 但暂时不激活 +gitlink-cli webhook +create \ + --url https://example.com/webhook \ + --events push \ + --active false \ + --description "Webhook for testing" +``` + +### 不同内容类型 +```bash +# JSON 格式(默认) +gitlink-cli webhook +create --url https://example.com/webhook --content-type json + +# Form 格式 +gitlink-cli webhook +create --url https://example.com/webhook --content-type form +``` + +## 错误处理 + +### 常见错误 + +#### 1. URL 无效 +```bash +Error: Invalid webhook URL format +``` +**原因**: URL 格式不正确或不是 HTTPS +**解决方案**: +```bash +# 使用 HTTPS URL +gitlink-cli webhook +create --url https://example.com/webhook +``` + +#### 2. 无效的事件类型 +```bash +Error: no valid events specified. Supported events: push, pull_request, issue, ... +``` +**原因**: 指定了不支持的事件类型 +**解决方案**: +```bash +# 查看支持的事件 +gitlink-cli webhook +events + +# 使用正确的事件类型 +gitlink-cli webhook +create --url https://example.com/webhook --events push,pull_request +``` + +#### 3. 权限不足 +```bash +Error: [403] You don't have permission to create webhooks +``` +**原因**: 用户不是仓库管理员 +**解决方案**: 确认您有仓库管理员权限 + +#### 4. Webhook 数量超限 +```bash +Error: [400] Webhook limit reached (maximum 20 webhooks per repository) +``` +**原因**: 仓库的 Webhook 数量已达上限 +**解决方案**: +```bash +# 删除不需要的 Webhook +gitlink-cli webhook +delete --id +``` + +## 最佳实践 + +### 1. 安全性 +```bash +# 始终为 Webhook 设置密钥 +gitlink-cli webhook +create \ + --url https://ci.example.com/webhook \ + --events push \ + --secret $(openssl rand -hex 32) + +# 使用 HTTPS URL +gitlink-cli webhook +create --url https://example.com/webhook +``` + +### 2. 事件选择 +```bash +# 只监听必要的事件 +gitlink-cli webhook +create \ + --url https://ci.example.com/webhook \ + --events push # CI 只需要 push 事件 +``` + +### 3. 描述清晰 +```bash +# 添加清晰的描述便于管理 +gitlink-cli webhook +create \ + --url https://jenkins.example.com/webhook \ + --events push,pull_request \ + --description "Production CI - Jenkins Pipeline" +``` + +## AI Agent 使用建议 + +### 验证 Webhook 创建 +```bash +# 创建后立即测试 +WEBHOOK_ID=$(gitlink-cli webhook +create --url $URL --events $EVENTS --format json | jq -r '.data.id') +gitlink-cli webhook +test --id $WEBHOOK_ID + +# 验证 Webhook 配置 +gitlink-cli webhook +info --id $WEBHOOK_ID +``` + +### 检查重复 Webhook +```bash +# 检查是否已存在相同 URL 的 Webhook +existing=$(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[] | select(.hook_url == "https://example.com/webhook") | .id') +if [ -n "$existing" ]; then + echo "Webhook already exists: $existing" +else + gitlink-cli webhook +create --url https://example.com/webhook +fi +``` + +## 安全建议 + +1. **使用密钥**: 始终设置 `--secret` 参数以验证请求来源 +2. **HTTPS**: 确保使用 HTTPS URL 保护数据传输 +3. **最小权限**: 只监听必要的事件类型 +4. **定期轮换**: 定期更新 Webhook 密钥 +5. **监控日志**: 监控 Webhook 请求日志以发现异常活动 + +## 注意事项 + +1. **URL 要求**: Webhook URL 必须是公网可访问的 HTTPS 地址 +2. **数量限制**: 每个仓库最多 20 个 Webhook +3. **权限要求**: 需要仓库管理员权限 +4. **事件格式**: 多个事件用逗号分隔,不要有空格 +5. **立即生效**: 创建后立即可用,除非设置 `--active false` + +## 相关命令 + +- `webhook +list` - 列出所有 Webhook +- `webhook +update` - 更新 Webhook 配置 +- `webhook +test` - 测试 Webhook +- `webhook +events` - 查看支持的事件类型 diff --git a/skills/gitlink-webhook/references/webhook-delete.md b/skills/gitlink-webhook/references/webhook-delete.md new file mode 100644 index 0000000..9f77f25 --- /dev/null +++ b/skills/gitlink-webhook/references/webhook-delete.md @@ -0,0 +1,282 @@ +# gitlink-cli webhook +delete + +删除指定的 Webhook。 + +## 命令格式 + +```bash +gitlink-cli webhook +delete [--owner OWNER] [--repo REPO] --id WEBHOOK_ID +``` + +## 参数说明 + +| 参数 | 短参数 | 说明 | 是否必须 | 默认值 | +|------|--------|------|----------|--------| +| `--owner` | `-o` | 仓库所有者 | 否 | 自动从 git remote 解析 | +| `--repo` | `-r` | 仓库名称 | 否 | 自动从 git remote 解析 | +| `--id` | `-i` | Webhook ID | **是** | - | + +## 返回值 + +### 成功返回 +```json +{ + "ok": true, + "data": { + "message": "Webhook deleted successfully" + }, + "meta": { + "identity": "user:myuser" + } +} +``` + +### 错误返回 +```json +{ + "ok": false, + "error": { + "code": 404, + "message": "Webhook not found", + "suggestion": "Please check the webhook ID" + } +} +``` + +## 使用示例 + +### 基本用法 +```bash +# 删除指定 Webhook +gitlink-cli webhook +delete --owner myuser --repo myrepo --id 456 + +# 在 git 仓库目录中删除(自动解析 owner/repo) +gitlink-cli webhook +delete --id 456 + +# 使用短参数 +gitlink-cli webhook +delete -i 456 +``` + +### 删除多个 Webhook +```bash +# 批量删除多个 Webhook +for id in 123 456 789; do + gitlink-cli webhook +delete --id $id +done +``` + +### 交互式删除 +```bash +# 先查看 Webhook 详情确认 +gitlink-cli webhook +info --id 456 + +# 确认后删除 +gitlink-cli webhook +delete --id 456 +``` + +## 错误处理 + +### 常见错误 + +#### 1. Webhook 不存在 +```bash +Error: [404] Webhook not found +``` +**原因**: 指定的 Webhook ID 不存在或已被删除 +**解决方案**: +```bash +# 先列出所有 Webhook 确认 ID +gitlink-cli webhook +list +``` + +#### 2. 权限不足 +```bash +Error: [403] You don't have permission to delete webhooks +``` +**原因**: 用户不是仓库管理员 +**解决方案**: 确认您有仓库管理员权限 + +#### 3. ID 参数缺失 +```bash +Error: required flag --id is missing +``` +**原因**: 没有提供 Webhook ID +**解决方案**: 指定要删除的 Webhook ID + +## 最佳实践 + +### 1. 删除前确认 +```bash +# 删除前先查看 Webhook 详情 +WEBHOOK_ID=456 +echo "About to delete webhook:" +gitlink-cli webhook +info --id $WEBHOOK_ID + +# 确认后删除 +read -p "Confirm deletion? (y/n) " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + gitlink-cli webhook +delete --id $WEBHOOK_ID +fi +``` + +### 2. 记录删除的 Webhook +```bash +# 删除前记录 Webhook 配置 +WEBHOOK_ID=456 +BACKUP_FILE="webhook_backup_$WEBHOOK_ID.json" +gitlink-cli webhook +info --id $WEBHOOK_ID --format json > $BACKUP_FILE +echo "Webhook config backed up to $BACKUP_FILE" + +# 然后删除 +gitlink-cli webhook +delete --id $WEBHOOK_ID +``` + +### 3. 批量清理不活跃的 Webhook +```bash +# 列出所有不活跃的 Webhook 并删除 +inactive_webhooks=$(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[] | select(.is_active == false) | .id') +for id in $inactive_webhooks; do + echo "Deleting inactive webhook: $id" + gitlink-cli webhook +delete --id $id +done +``` + +## AI Agent 使用建议 + +### 安全删除流程 +```bash +# AI Agent 删除 Webhook 的安全流程 +delete_webhook_safely() { + WEBHOOK_ID=$1 + + # 1. 检查 Webhook 是否存在 + if ! gitlink-cli webhook +info --id $WEBHOOK_ID --format json >/dev/null 2>&1; then + echo "Webhook $WEBHOOK_ID not found" + return 1 + fi + + # 2. 备份配置 + gitlink-cli webhook +info --id $WEBHOOK_ID --format json > "webhook_backup_$WEBHOOK_ID.json" + + # 3. 删除 Webhook + if gitlink-cli webhook +delete --id $WEBHOOK_ID; then + echo "Webhook $WEBHOOK_ID deleted successfully" + return 0 + else + echo "Failed to delete webhook $WEBHOOK_ID" + return 1 + fi +} +``` + +### 批量删除 Webhook +```bash +# 删除所有匹配特定条件的 Webhook +delete_webhooks_by_url() { + URL_PATTERN=$1 + + # 找到匹配的 Webhook + webhook_ids=$(gitlink-cli webhook +list --format json | \ + jq -r ".data.webhooks[] | select(.hook_url | contains(\"$URL_PATTERN\")) | .id") + + # 逐个删除 + for id in $webhook_ids; do + echo "Deleting webhook $id with URL matching $URL_PATTERN" + gitlink-cli webhook +delete --id $id + done +} + +# 使用示例:删除所有指向旧服务器的 Webhook +delete_webhooks_by_url "old-server.example.com" +``` + +### 验证删除 +```bash +# 删除 Webhook 并验证 +WEBHOOK_ID=456 + +# 删除前检查 +if gitlink-cli webhook +info --id $WEBHOOK_ID >/dev/null 2>&1; then + echo "Webhook exists, deleting..." + gitlink-cli webhook +delete --id $WEBHOOK_ID + + # 验证删除成功 + if ! gitlink-cli webhook +info --id $WEBHOOK_ID >/dev/null 2>&1; then + echo "Webhook deleted successfully" + else + echo "Webhook still exists after deletion" + fi +else + echo "Webhook not found" +fi +``` + +## 注意事项 + +1. **不可恢复**: 删除操作不可逆,请谨慎操作 +2. **立即生效**: 删除后立即停止接收事件 +3. **权限要求**: 需要仓库管理员权限 +4. **API 特性**: GitLink API 在删除时可能返回错误信息,但实际删除成功 +5. **验证删除**: 建议删除后验证 Webhook 是否已删除 + +## 常见使用场景 + +### 场景1: 清理测试 Webhook +```bash +# 删除所有测试环境的 Webhook +test_webhooks=$(gitlink-cli webhook +list --format json | \ + jq -r '.data.webhooks[] | select(.description | contains("test")) | .id') + +for id in $test_webhooks; do + echo "Deleting test webhook: $id" + gitlink-cli webhook +delete --id $id +done +``` + +### 场景2: 迁移到新 URL +```bash +# 迁移 Webhook 到新 URL +OLD_WEBHOOK_ID=456 +OLD_URL=$(gitlink-cli webhook +info --id $OLD_WEBHOOK_ID --format json | jq -r '.data.hook_url') +NEW_URL="https://new-server.example.com/webhook" + +# 创建新 Webhook +NEW_WEBHOOK_ID=$(gitlink-cli webhook +create --url $NEW_URL --events push --format json | jq -r '.data.id') + +# 测试新 Webhook +gitlink-cli webhook +test --id $NEW_WEBHOOK_ID + +# 确认新 Webhook 工作后删除旧 Webhook +gitlink-cli webhook +delete --id $OLD_WEBHOOK_ID +``` + +### 场景3: 批量重构 Webhook +```bash +# 重构所有 Webhook,重新创建后删除旧的 +# 1. 备份现有配置 +gitlink-cli webhook +list --format json > webhook_config_backup.json + +# 2. 根据备份创建新配置(可能使用不同的 URL 或事件) + +# 3. 删除旧的 Webhook +old_ids=$(jq -r '.data.webhooks[].id' webhook_config_backup.json) +for id in $old_ids; do + gitlink-cli webhook +delete --id $id +done +``` + +## 安全建议 + +1. **删除前备份**: 删除前备份 Webhook 配置 +2. **确认操作**: 删除前确认 Webhook ID 和配置 +3. **逐步删除**: 批量删除时逐步进行,避免误删 +4. **验证删除**: 删除后验证 Webhook 已被删除 +5. **权限控制**: 限制删除权限给授权用户 + +## 相关命令 + +- `webhook +list` - 列出所有 Webhook +- `webhook +info` - 查看 Webhook 详情 +- `webhook +create` - 创建新 Webhook +- `webhook +update` - 更新 Webhook(可以先用 `--active false` 停用) diff --git a/skills/gitlink-webhook/references/webhook-info.md b/skills/gitlink-webhook/references/webhook-info.md new file mode 100644 index 0000000..16833f4 --- /dev/null +++ b/skills/gitlink-webhook/references/webhook-info.md @@ -0,0 +1,382 @@ +# gitlink-cli webhook +info + +查看指定 Webhook 的详细信息。 + +## 命令格式 + +```bash +gitlink-cli webhook +info [--owner OWNER] [--repo REPO] --id WEBHOOK_ID +``` + +## 参数说明 + +| 参数 | 短参数 | 说明 | 是否必须 | 默认值 | +|------|--------|------|----------|--------| +| `--owner` | `-o` | 仓库所有者 | 否 | 自动从 git remote 解析 | +| `--repo` | `-r` | 仓库名称 | 否 | 自动从 git remote 解析 | +| `--id` | `-i` | Webhook ID | **是** | - | + +## 返回值 + +### 成功返回 +```json +{ + "ok": true, + "data": { + "id": "456", + "hook_url": "https://ci.example.com/webhook", + "events": ["push", "pull_request", "issue"], + "is_active": true, + "content_type": "json", + "description": "CI/CD automation webhook", + "project": { + "owner": "myuser", + "repo": "myrepo", + "identifier": "myuser/myrepo" + }, + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-15T12:30:00Z", + "last_delivery": { + "timestamp": "2024-01-15T14:25:00Z", + "status": "success", + "event": "push", + "duration_ms": 245 + }, + "delivery_statistics": { + "total_deliveries": 1523, + "successful_deliveries": 1498, + "failed_deliveries": 25, + "success_rate": 98.36 + } + }, + "meta": { + "identity": "user:myuser" + } +} +``` + +### 错误返回 +```json +{ + "ok": false, + "error": { + "code": 404, + "message": "Webhook not found", + "suggestion": "Please check the webhook ID" + } +} +``` + +## 使用示例 + +### 基本用法 +```bash +# 查看 Webhook 详情 +gitlink-cli webhook +info --owner myuser --repo myrepo --id 456 + +# 在 git 仓库目录中查看(自动解析 owner/repo) +gitlink-cli webhook +info --id 456 + +# 使用短参数 +gitlink-cli webhook +info -i 456 +``` + +### 不同输出格式 +```bash +# JSON 格式(默认,便于解析) +gitlink-cli webhook +info --id 456 --format json + +# Table 格式(更易阅读) +gitlink-cli webhook +info --id 456 --format table + +# YAML 格式 +gitlink-cli webhook +info --id 456 --format yaml +``` + +### 提取特定信息 +```bash +# 使用 jq 提取 Webhook URL +gitlink-cli webhook +info --id 456 --format json | jq -r '.data.hook_url' + +# 查看 Webhook 是否激活 +gitlink-cli webhook +info --id 456 --format json | jq -r '.data.is_active' + +# 查看监听的事件类型 +gitlink-cli webhook +info --id 456 --format json | jq -r '.data.events[]' + +# 查看统计信息 +gitlink-cli webhook +info --id 456 --format json | jq '.data.delivery_statistics' +``` + +### 比较两个 Webhook +```bash +# 比较两个 Webhook 的配置 +echo "=== Webhook 456 ===" +gitlink-cli webhook +info --id 456 + +echo "=== Webhook 789 ===" +gitlink-cli webhook +info --id 789 +``` + +## 错误处理 + +### 常见错误 + +#### 1. Webhook 不存在 +```bash +Error: [404] Webhook not found +``` +**原因**: 指定的 Webhook ID 不存在 +**解决方案**: +```bash +# 先列出所有 Webhook 找到正确 ID +gitlink-cli webhook +list +``` + +#### 2. 权限不足 +```bash +Error: [403] You don't have permission to view webhook details +``` +**原因**: 用户没有仓库访问权限 +**解决方案**: 确认您是仓库成员 + +#### 3. ID 参数缺失 +```bash +Error: required flag --id is missing +``` +**原因**: 没有提供 Webhook ID +**解决方案**: 指定要查看的 Webhook ID + +## 最佳实践 + +### 1. 更新前查看 +```bash +# 更新 Webhook 前先查看当前配置 +WEBHOOK_ID=456 +echo "Current configuration:" +gitlink-cli webhook +info --id $WEBHOOK_ID + +# 然后进行更新 +gitlink-cli webhook +update --id $WEBHOOK_ID --url $NEW_URL +``` + +### 2. 批量查看 Webhook 信息 +```bash +# 查看所有 Webhook 的简要信息 +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + echo "=== Webhook $id ===" + gitlink-cli webhook +info --id $WEBHOOK_ID --format json | jq -r '.data | "\(.hook_url) - \(.description)"' +done +``` + +### 3. 验证 Webhook 配置 +```bash +# 检查 Webhook 是否正确配置 +check_webhook_config() { + WEBHOOK_ID=$1 + + # 获取 Webhook 信息 + info=$(gitlink-cli webhook +info --id $WEBHOOK_ID --format json) + + # 检查是否激活 + is_active=$(echo $info | jq -r '.data.is_active') + if [ "$is_active" != "true" ]; then + echo "WARNING: Webhook is not active" + fi + + # 检查是否有事件 + events=$(echo $info | jq -r '.data.events | length') + if [ "$events" -eq 0 ]; then + echo "WARNING: No events configured" + fi + + # 检查 URL 是否有效 + url=$(echo $info | jq -r '.data.hook_url') + if [[ ! $url =~ ^https:// ]]; then + echo "WARNING: URL does not use HTTPS" + fi + + # 显示成功率 + success_rate=$(echo $info | jq -r '.data.delivery_statistics.success_rate') + echo "Success rate: $success_rate%" +} +``` + +## AI Agent 使用建议 + +### 自动化 Webhook 配置检查 +```bash +# AI Agent 检查 Webhook 配置的自动化脚本 +analyze_webhook() { + WEBHOOK_ID=$1 + OUTPUT_FORMAT="${2:-json}" + + info=$(gitlink-cli webhook +info --id $WEBHOOK_ID --format $OUTPUT_FORMAT) + + if [ "$OUTPUT_FORMAT" = "json" ]; then + # JSON 格式便于解析 + echo "$info" | jq '.data | { + id, + url: .hook_url, + active: .is_active, + events: .events, + success_rate: .delivery_statistics.success_rate, + last_delivery: .last_delivery.timestamp + }' + else + # 其他格式直接输出 + echo "$info" + fi +} + +# 批量分析所有 Webhook +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + analyze_webhook $id +done +``` + +### Webhook 健康检查 +```bash +# 检查 Webhook 健康状态 +check_webhook_health() { + WEBHOOK_ID=$1 + + info=$(gitlink-cli webhook +info --id $WEBHOOK_ID --format json) + + # 提取关键指标 + is_active=$(echo $info | jq -r '.data.is_active') + success_rate=$(echo $info | jq -r '.data.delivery_statistics.success_rate') + last_delivery=$(echo $info | jq -r '.data.last_delivery.timestamp') + + # 健康评分 + health_score=100 + issues=() + + if [ "$is_active" != "true" ]; then + health_score=$((health_score - 50)) + issues+=("Webhook is not active") + fi + + if (( $(echo "$success_rate < 95" | bc -l) )); then + health_score=$((health_score - 30)) + issues+=("Success rate below 95%: $success_rate%") + fi + + if [ -z "$last_delivery" ] || [ "$last_delivery" = "null" ]; then + health_score=$((health_score - 20)) + issues+=("No recent deliveries") + fi + + # 输出结果 + echo "Webhook $WEBHOOK_ID Health Check" + echo "Health Score: $health_score/100" + if [ ${#issues[@]} -gt 0 ]; then + echo "Issues found:" + printf '%s\n' "${issues[@]}" + else + echo "✓ Webhook is healthy" + fi +} +``` + +### 配置差异分析 +```bash +# 比较两个 Webhook 的配置差异 +compare_webhooks() { + ID1=$1 + ID2=$2 + + info1=$(gitlink-cli webhook +info --id $ID1 --format json) + info2=$(gitlink-cli webhook +info --id $ID2 --format json) + + echo "=== Webhook Comparison ===" + echo "Webhook 1: $ID1" + echo "Webhook 2: $ID2" + echo + + # 比较 URL + url1=$(echo $info1 | jq -r '.data.hook_url') + url2=$(echo $info2 | jq -r '.data.hook_url') + echo "URL:" + echo " $ID1: $url1" + echo " $ID2: $url2" + [ "$url1" = "$url2" ] && echo " Status: Same" || echo " Status: Different" + echo + + # 比较事件 + events1=$(echo $info1 | jq -r '.data.events | sort | join(",")') + events2=$(echo $info2 | jq -r '.data.events | sort | join(",")') + echo "Events:" + echo " $ID1: $events1" + echo " $ID2: $events2" + [ "$events1" = "$events2" ] && echo " Status: Same" || echo " Status: Different" + echo + + # 比较激活状态 + active1=$(echo $info1 | jq -r '.data.is_active') + active2=$(echo $info2 | jq -r '.data.is_active') + echo "Active Status:" + echo " $ID1: $active1" + echo " $ID2: $active2" + [ "$active1" = "$active2" ] && echo " Status: Same" || echo " Status: Different" +} +``` + +## 注意事项 + +1. **权限要求**: 至少需要仓库读取权限 +2. **详细信息**: 包含 Webhook 的所有配置和统计信息 +3. **统计数据**: 部分统计信息可能为空,特别是新创建的 Webhook +4. **时间格式**: 所有时间戳均为 ISO 8601 格式(UTC) +5. **敏感信息**: 输出可能包含敏感信息,注意保护 + +## 常见使用场景 + +### 场景1: 确认 Webhook 配置 +```bash +# 确认 Webhook 配置是否正确 +gitlink-cli webhook +info --id 456 + +# 检查关键配置 +gitlink-cli webhook +info --id 456 --format json | jq -r '{ + url: .data.hook_url, + events: .data.events, + active: .data.is_active, + success_rate: .data.delivery_statistics.success_rate +}' +``` + +### 场景2: 故障排查 +```bash +# Webhook 出问题时查看详细信息 +gitlink-cli webhook +info --id 456 + +# 检查最近一次投递情况 +gitlink-cli webhook +info --id 456 --format json | jq '.data.last_delivery' + +# 查看失败统计 +gitlink-cli webhook +info --id 456 --format json | jq '.data.delivery_statistics' +``` + +### 场景3: 配置审计 +```bash +# 审计所有 Webhook 配置 +echo "=== Webhook Configuration Audit ===" +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + echo "Webhook $id:" + gitlink-cli webhook +info --id $id --format json | jq -r '{ + url: .data.hook_url, + events: .data.events | join(","), + active: .data.is_active, + description: .description + }' + echo +done +``` + +## 相关命令 + +- `webhook +list` - 列出所有 Webhook +- `webhook +create` - 创建新 Webhook +- `webhook +update` - 更新 Webhook 配置 +- `webhook +test` - 测试 Webhook diff --git a/skills/gitlink-webhook/references/webhook-list.md b/skills/gitlink-webhook/references/webhook-list.md new file mode 100644 index 0000000..e08e7c0 --- /dev/null +++ b/skills/gitlink-webhook/references/webhook-list.md @@ -0,0 +1,162 @@ +# gitlink-cli webhook +list + +列出仓库的所有 Webhook。 + +## 命令格式 + +```bash +gitlink-cli webhook +list [--owner OWNER] [--repo REPO] [--page PAGE] [--limit LIMIT] +``` + +## 参数说明 + +| 参数 | 短参数 | 说明 | 是否必须 | 默认值 | +|------|--------|------|----------|--------| +| `--owner` | `-o` | 仓库所有者 | 否 | 自动从 git remote 解析 | +| `--repo` | `-r` | 仓库名称 | 否 | 自动从 git remote 解析 | +| `--page` | `-p` | 页码 | 否 | 1 | +| `--limit` | `-l` | 每页数量 | 否 | 20 | + +## 返回值 + +### 成功返回 +```json +{ + "ok": true, + "data": { + "webhooks": [ + { + "id": "123", + "hook_url": "https://example.com/webhook", + "events": ["push", "pull_request"], + "is_active": true, + "content_type": "json", + "description": "CI/CD webhook", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z" + } + ], + "total_count": 5, + "page": 1, + "limit": 20 + }, + "meta": { + "page": 1, + "limit": 20, + "total_count": 5 + } +} +``` + +### 错误返回 +```json +{ + "ok": false, + "error": { + "code": 401, + "message": "Authentication failed", + "suggestion": "Please run 'gitlink-cli auth login' to authenticate" + } +} +``` + +## 使用示例 + +### 基本用法 +```bash +# 列出当前仓库的 Webhook(需要在 git 仓库目录中) +gitlink-cli webhook +list + +# 列出指定仓库的 Webhook +gitlink-cli webhook +list --owner myuser --repo myrepo + +# 分页显示 +gitlink-cli webhook +list --owner myuser --repo myrepo --page 2 --limit 10 +``` + +### JSON 格式输出(AI Agent 使用) +```bash +# 获取 JSON 格式输出便于解析 +gitlink-cli webhook +list --owner myuser --repo myrepo --format json + +# 使用 jq 处理输出 +gitlink-cli webhook +list --format json | jq '.data.webhooks[] | select(.is_active == true)' + +# 统计 Webhook 数量 +gitlink-cli webhook +list --format json | jq '.data.total_count' +``` + +### Table 格式输出 +```bash +# 表格格式更易阅读(默认) +gitlink-cli webhook +list --format table + +# 指定表格格式 +gitlink-cli webhook +list --owner myuser --repo myrepo --format table +``` + +## 错误处理 + +### 常见错误 + +#### 1. 认证失败 +```bash +Error: [401] Authentication failed +``` +**原因**: Token 过期或无效 +**解决方案**: +```bash +gitlink-cli auth login +``` + +#### 2. 权限不足 +```bash +Error: [403] You don't have permission to view webhooks +``` +**原因**: 用户没有仓库访问权限 +**解决方案**: 确认您是仓库成员或公开项目 + +#### 3. 仓库不存在 +```bash +Error: [404] Repository not found +``` +**原因**: 仓库名称或所有者错误 +**解决方案**: 使用 `gitlink-cli repo +list` 确认仓库名称 + +## AI Agent 使用建议 + +### 检查 Webhook 配置 +```bash +# 检查是否已配置特定类型的 Webhook +gitlink-cli webhook +list --format json | jq '.data.webhooks[] | select(.hook_url | contains("ci-system"))' + +# 检查是否有激活的 Webhook +gitlink-cli webhook +list --format json | jq '.data.webhooks[] | select(.is_active == true)' + +# 获取所有 Webhook 的 URL +gitlink-cli webhook +list --format json | jq '.data.webhooks[].hook_url' +``` + +### 批量操作 +```bash +# 获取所有 Webhook ID +webhook_ids=$(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id') + +# 批量测试所有 Webhook +for id in $webhook_ids; do + gitlink-cli webhook +test --id $id +done +``` + +## 注意事项 + +1. **分页查询**: 默认每页显示 20 个,使用 `--limit` 可调整 +2. **权限要求**: 至少需要仓库读取权限 +3. **自动解析**: 在 git 仓库目录中可省略 `--owner` 和 `--repo` +4. **格式选择**: AI Agent 建议使用 `--format json` 便于解析 + +## 相关命令 + +- `webhook +create` - 创建新 Webhook +- `webhook +info` - 查看特定 Webhook 详情 +- `webhook +events` - 查看支持的事件类型 diff --git a/skills/gitlink-webhook/references/webhook-test.md b/skills/gitlink-webhook/references/webhook-test.md new file mode 100644 index 0000000..eec922c --- /dev/null +++ b/skills/gitlink-webhook/references/webhook-test.md @@ -0,0 +1,378 @@ +# gitlink-cli webhook +test + +测试 Webhook 连接性,发送测试事件验证 Webhook 是否正常工作。 + +## 命令格式 + +```bash +gitlink-cli webhook +test \ + [--owner OWNER] \ + [--repo REPO] \ + --id WEBHOOK_ID \ + [--event EVENT_TYPE] +``` + +## 参数说明 + +| 参数 | 短参数 | 说明 | 是否必须 | 默认值 | +|------|--------|------|----------|--------| +| `--owner` | `-o` | 仓库所有者 | 否 | 自动从 git remote 解析 | +| `--repo` | `-r` | 仓库名称 | 否 | 自动从 git remote 解析 | +| `--id` | `-i` | Webhook ID | **是** | - | +| `--event` | `-e` | 测试的事件类型 | 否 | `push` | + +### 支持的测试事件 +- `push` - 推送事件(默认) +- `pull_request` - Pull 请求事件 +- `issue` - Issue 事件 +- 其他支持的事件类型 + +## 返回值 + +### 成功返回 +```json +{ + "ok": true, + "data": { + "message": "Webhook test triggered successfully", + "webhook_id": "456", + "event_type": "push", + "delivered": true, + "response_status": 200, + "response_body": "Webhook received" + }, + "meta": { + "identity": "user:myuser" + } +} +``` + +### Webhook 不可达 +```json +{ + "ok": true, + "data": { + "message": "Webhook test completed with warnings", + "webhook_id": "456", + "event_type": "push", + "delivered": false, + "error": "Connection timeout", + "suggestion": "Please check if the webhook URL is accessible" + } +} +``` + +### 错误返回 +```json +{ + "ok": false, + "error": { + "code": 404, + "message": "Webhook not found", + "suggestion": "Please check the webhook ID" + } +} +``` + +## 使用示例 + +### 基本测试 +```bash +# 测试 Webhook(默认使用 push 事件) +gitlink-cli webhook +test --owner myuser --repo myrepo --id 456 + +# 在 git 仓库目录中测试 +gitlink-cli webhook +test --id 456 + +# 使用短参数 +gitlink-cli webhook +test -i 456 +``` + +### 测试特定事件类型 +```bash +# 测试 pull_request 事件 +gitlink-cli webhook +test --id 456 --event pull_request + +# 测试 issue 事件 +gitlink-cli webhook +test --id 456 --event issue + +# 测试多种事件类型 +for event in push pull_request issue; do + echo "Testing event: $event" + gitlink-cli webhook +test --id 456 --event $event +done +``` + +### 批量测试所有 Webhook +```bash +# 测试仓库的所有 Webhook +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + echo "Testing webhook: $id" + gitlink-cli webhook +test --id $id +done +``` + +### 测试新创建的 Webhook +```bash +# 创建后立即测试 +WEBHOOK_ID=$(gitlink-cli webhook +create --url https://example.com/webhook --events push --format json | jq -r '.data.id') +echo "Testing new webhook: $WEBHOOK_ID" +gitlink-cli webhook +test --id $WEBHOOK_ID +``` + +## 错误处理 + +### 常见错误 + +#### 1. Webhook 不存在 +```bash +Error: [404] Webhook not found +``` +**原因**: 指定的 Webhook ID 不存在 +**解决方案**: +```bash +# 先列出所有 Webhook 找到正确 ID +gitlink-cli webhook +list +``` + +#### 2. 无效的事件类型 +```bash +Error: unsupported event type: custom_event +``` +**原因**: 指定了不支持的事件类型 +**解决方案**: +```bash +# 查看支持的事件类型 +gitlink-cli webhook +events + +# 使用支持的事件类型 +gitlink-cli webhook +test --id 456 --event push +``` + +#### 3. Webhook URL 不可达 +```bash +Warning: Webhook delivery failed - Connection timeout +``` +**原因**: Webhook URL 无法访问或服务器无响应 +**解决方案**: +```bash +# 1. 检查 URL 是否正确 +gitlink-cli webhook +info --id 456 + +# 2. 手动测试 URL +curl -X POST https://your-webhook-url.com/test + +# 3. 检查服务器防火墙和网络设置 +``` + +#### 4. SSL 证书问题 +```bash +Warning: Webhook delivery failed - SSL certificate verify failed +``` +**原因**: Webhook 服务器的 SSL 证书有问题 +**解决方案**: +```bash +# 检查 SSL 证书 +curl -v https://your-webhook-url.com/test + +# 更新服务器的 SSL 证书 +``` + +## 最佳实践 + +### 1. 创建后测试 +```bash +# 创建 Webhook 后立即测试 +WEBHOOK_ID=$(gitlink-cli webhook +create --url $URL --events $EVENTS --format json | jq -r '.data.id') +if gitlink-cli webhook +test --id $WEBHOOK_ID; then + echo "Webhook created and tested successfully" +else + echo "Webhook test failed, please check configuration" + gitlink-cli webhook +delete --id $WEBHOOK_ID +fi +``` + +### 2. 更新后测试 +```bash +# 更新 Webhook 后测试 +gitlink-cli webhook +update --id 456 --url $NEW_URL +gitlink-cli webhook +test --id 456 +``` + +### 3. 定期测试 +```bash +# 定期测试所有 Webhook 确保正常工作 +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + if ! gitlink-cli webhook +test --id $id; then + echo "WARNING: Webhook $id test failed" + fi +done +``` + +## AI Agent 使用建议 + +### 自动化测试流程 +```bash +# AI Agent 测试 Webhook 的完整流程 +test_and_fix_webhook() { + WEBHOOK_ID=$1 + MAX_RETRIES=3 + RETRY_COUNT=0 + + while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do + echo "Testing webhook $WEBHOOK_ID (attempt $((RETRY_COUNT + 1))/$MAX_RETRIES)" + + # 测试 Webhook + if gitlink-cli webhook +test --id $WEBHOOK_ID; then + echo "✓ Webhook test successful" + return 0 + fi + + # 测试失败,等待后重试 + RETRY_COUNT=$((RETRY_COUNT + 1)) + if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then + echo "Test failed, waiting 5 seconds before retry..." + sleep 5 + fi + done + + echo "✗ Webhook test failed after $MAX_RETRIES attempts" + return 1 +} +``` + +### 监控 Webhook 健康 +```bash +# 定期检查所有 Webhook 的健康状态 +check_all_webhooks_health() { + REPORT_FILE="webhook_health_report_$(date +%Y%m%d_%H%M%S).txt" + + echo "Webhook Health Check Report - $(date)" > $REPORT_FILE + echo "=================================" >> $REPORT_FILE + + for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + webhook_info=$(gitlink-cli webhook +info --id $id --format json) + webhook_url=$(echo $webhook_info | jq -r '.data.hook_url') + webhook_status=$(echo $webhook_info | jq -r '.data.is_active') + + echo -e "\nWebhook ID: $id" >> $REPORT_FILE + echo "URL: $webhook_url" >> $REPORT_FILE + echo "Active: $webhook_status" >> $REPORT_FILE + echo "Test Result:" >> $REPORT_FILE + + if gitlink-cli webhook +test --id $id >> $REPORT_FILE 2>&1; then + echo "Status: HEALTHY ✓" >> $REPORT_FILE + else + echo "Status: UNHEALTHY ✗" >> $REPORT_FILE + fi + done + + cat $REPORT_FILE +} +``` + +### 故障诊断 +```bash +# 诊断 Webhook 问题 +diagnose_webhook() { + WEBHOOK_ID=$1 + + echo "=== Webhook Diagnosis ===" + echo "Webhook ID: $WEBHOOK_ID" + echo + + # 1. 检查 Webhook 是否存在 + echo "1. Checking webhook existence..." + if ! gitlink-cli webhook +info --id $WEBHOOK_ID >/dev/null 2>&1; then + echo " ✗ Webhook not found" + return 1 + fi + echo " ✓ Webhook exists" + + # 2. 获取 Webhook 配置 + echo "2. Webhook configuration:" + gitlink-cli webhook +info --id $WEBHOOK_ID + + # 3. 测试网络连通性 + echo "3. Testing network connectivity..." + WEBHOOK_URL=$(gitlink-cli webhook +info --id $WEBHOOK_ID --format json | jq -r '.data.hook_url') + if curl -s -o /dev/null -w "%{http_code}" "$WEBHOOK_URL" | grep -q "200\|301\|302"; then + echo " ✓ URL is accessible" + else + echo " ✗ URL is not accessible" + fi + + # 4. 测试 Webhook + echo "4. Testing webhook delivery..." + if gitlink-cli webhook +test --id $WEBHOOK_ID; then + echo " ✓ Webhook test successful" + else + echo " ✗ Webhook test failed" + fi +} +``` + +## 注意事项 + +1. **测试限制**: 测试事件不会触发实际的业务逻辑,仅验证连通性 +2. **请求格式**: 测试请求的格式与真实事件略有不同 +3. **响应时间**: Webhook 应在 10 秒内响应,否则超时 +4. **重试机制**: 测试失败不会触发 GitLink 的重试机制 +5. **权限要求**: 需要仓库管理员权限 + +## 常见使用场景 + +### 场景1: 验证新 Webhook +```bash +# 创建 Webhook 后验证配置 +WEBHOOK_ID=$(gitlink-cli webhook +create \ + --url https://ci.example.com/webhook \ + --events push,pull_request \ + --format json | jq -r '.data.id') + +# 测试各种事件类型 +for event in push pull_request; do + echo "Testing $event event..." + gitlink-cli webhook +test --id $WEBHOOK_ID --event $event +done +``` + +### 场景2: 故障排查 +```bash +# Webhook 未触发时进行测试 +# 1. 检查 Webhook 是否激活 +gitlink-cli webhook +info --id 456 + +# 2. 测试 Webhook 连通性 +gitlink-cli webhook +test --id 456 + +# 3. 查看详细错误信息 +gitlink-cli webhook +test --id 456 --debug +``` + +### 场景3: 批量验证 +```bash +# 验证所有 Webhook 在服务器迁移后是否正常 +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + echo "Testing webhook $id..." + if ! gitlink-cli webhook +test --id $id; then + echo "WARNING: Webhook $id needs attention" + # 可以在这里添加自动修复逻辑 + fi +done +``` + +## 安全建议 + +1. **避免敏感数据**: 测试事件可能包含真实数据,注意隐私保护 +2. **测试频率**: 不要过于频繁测试,避免对服务器造成压力 +3. **错误信息**: 测试失败时的错误信息可能暴露系统细节 +4. **访问控制**: 确保测试 URL 只暴露必要的信息 + +## 相关命令 + +- `webhook +list` - 列出所有 Webhook +- `webhook +info` - 查看 Webhook 详情 +- `webhook +create` - 创建新 Webhook +- `webhook +update` - 更新 Webhook 配置 +- `webhook +events` - 查看支持的事件类型 diff --git a/skills/gitlink-webhook/references/webhook-update.md b/skills/gitlink-webhook/references/webhook-update.md new file mode 100644 index 0000000..7958419 --- /dev/null +++ b/skills/gitlink-webhook/references/webhook-update.md @@ -0,0 +1,277 @@ +# gitlink-cli webhook +update + +更新现有 Webhook 的配置。 + +## 命令格式 + +```bash +gitlink-cli webhook +update \ + --owner OWNER \ + --repo REPO \ + --id WEBHOOK_ID \ + [--url URL] \ + [--events EVENTS] \ + [--active ACTIVE] \ + [--content_type CONTENT_TYPE] \ + [--secret SECRET] \ + [--description DESCRIPTION] +``` + +## 参数说明 + +| 参数 | 短参数 | 说明 | 是否必须 | 默认值 | +|------|--------|------|----------|--------| +| `--owner` | `-o` | 仓库所有者 | 否 | 自动从 git remote 解析 | +| `--repo` | `-r` | 仓库名称 | 否 | 自动从 git remote 解析 | +| `--id` | `-i` | Webhook ID | **是** | - | +| `--url` | `-u` | 新的 Webhook URL | 否 | 不修改 | +| `--events` | `-e` | 新的触发事件 | 否 | 不修改 | +| `--active` | - | 是否激活 | 否 | 不修改 | +| `--content_type` | - | 内容类型 | 否 | 不修改 | +| `--secret` | - | 新的密钥 | 否 | 不修改 | +| `--description` | `-d` | 新的描述 | 否 | 不修改 | + +## 返回值 + +### 成功返回 +```json +{ + "ok": true, + "data": { + "id": "456", + "hook_url": "https://new-url.example.com/webhook", + "events": ["push", "pull_request", "issue"], + "is_active": false, + "content_type": "json", + "description": "Updated webhook description", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-02T12:00:00Z" + }, + "meta": { + "identity": "user:myuser" + } +} +``` + +### 错误返回 +```json +{ + "ok": false, + "error": { + "code": 404, + "message": "Webhook not found", + "suggestion": "Please check the webhook ID" + } +} +``` + +## 使用示例 + +### 更新 URL +```bash +# 修改 Webhook 回调地址 +gitlink-cli webhook +update --owner myuser --repo myrepo --id 456 --url https://new-url.example.com/webhook + +# 在 git 仓库目录中更新 +gitlink-cli webhook +update --id 456 --url https://new-url.example.com/webhook +``` + +### 更新事件 +```bash +# 添加更多事件类型 +gitlink-cli webhook +update --id 456 --events push,pull_request,issue,issue_comment + +# 减少事件类型(只监听 push) +gitlink-cli webhook +update --id 456 --events push +``` + +### 激活/停用 Webhook +```bash +# 停用 Webhook +gitlink-cli webhook +update --id 456 --active false + +# 重新激活 Webhook +gitlink-cli webhook +update --id 456 --active true +``` + +### 更新密钥 +```bash +# 更新 Webhook 密钥(推荐定期轮换) +gitlink-cli webhook +update --id 456 --secret new-secret-key-2024 +``` + +### 更新描述 +```bash +# 更新 Webhook 描述 +gitlink-cli webhook +update --id 456 --description "Updated for new CI/CD pipeline" +``` + +### 批量更新多个属性 +```bash +# 同时更新多个属性 +gitlink-cli webhook +update \ + --id 456 \ + --url https://new-url.example.com/webhook \ + --events push,pull_request,issue \ + --secret new-secret \ + --description "Comprehensive webhook update" +``` + +## 错误处理 + +### 常见错误 + +#### 1. Webhook 不存在 +```bash +Error: [404] Webhook not found +``` +**原因**: 指定的 Webhook ID 不存在 +**解决方案**: +```bash +# 先列出所有 Webhook 找到正确 ID +gitlink-cli webhook +list +``` + +#### 2. 无效的事件类型 +```bash +Error: no valid events specified +``` +**原因**: 指定了不支持的事件类型 +**解决方案**: +```bash +# 查看支持的事件 +gitlink-cli webhook +events +``` + +#### 3. 权限不足 +```bash +Error: [403] You don't have permission to update webhooks +``` +**原因**: 用户不是仓库管理员 +**解决方案**: 确认您有仓库管理员权限 + +#### 4. 没有指定更新字段 +```bash +Error: no fields specified for update +``` +**原因**: 没有提供任何要更新的字段 +**解决方案**: 至少指定一个要更新的字段 + +## 最佳实践 + +### 1. 密钥轮换 +```bash +# 定期更新密钥(建议每3个月) +gitlink-cli webhook +update --id 456 --secret $(openssl rand -hex 32) +``` + +### 2. 临时停用 +```bash +# 临时停用 Webhook 进行维护 +gitlink-cli webhook +update --id 456 --active false + +# 维护完成后重新激活 +gitlink-cli webhook +update --id 456 --active true +``` + +### 3. 渐进式更新 +```bash +# 先测试新配置 +gitlink-cli webhook +update --id 456 --url https://new-url.example.com/webhook --active false +gitlink-cli webhook +test --id 456 + +# 确认无误后激活 +gitlink-cli webhook +update --id 456 --active true +``` + +## AI Agent 使用建议 + +### 批量更新 Webhook +```bash +# 为所有 Webhook 添加新事件 +for id in $(gitlink-cli webhook +list --format json | jq -r '.data.webhooks[].id'); do + # 获取当前事件 + current_events=$(gitlink-cli webhook +info --id $id --format json | jq -r '.data.events | join(",")') + # 添加新事件 + gitlink-cli webhook +update --id $id --events "$current_events,issue_comment" +done +``` + +### 验证更新 +```bash +# 更新后立即验证 +WEBHOOK_ID=456 +gitlink-cli webhook +update --id $WEBHOOK_ID --url $NEW_URL +gitlink-cli webhook +info --id $WEBHOOK_ID +gitlink-cli webhook +test --id $WEBHOOK_ID +``` + +### 检查更新前后差异 +```bash +# 查看更新前后配置差异 +BEFORE=$(gitlink-cli webhook +info --id 456 --format json) +gitlink-cli webhook +update --id 456 --url $NEW_URL +AFTER=$(gitlink-cli webhook +info --id 456 --format json) + +# 对比差异(需要 jq 工具) +echo "Before:" && echo "$BEFORE" | jq '.data' +echo "After:" && echo "$AFTER" | jq '.data' +``` + +## 安全建议 + +1. **密钥轮换**: 定期更新 Webhook 密钥,建议每3个月一次 +2. **测试新配置**: 更新重要配置前先停用,测试后再激活 +3. **备份配置**: 更新前记录原配置,便于回滚 +4. **权限验证**: 确保只有授权用户能修改 Webhook +5. **审计日志**: 记录所有 Webhook 配置变更 + +## 注意事项 + +1. **部分更新**: 只更新指定的字段,未指定的字段保持不变 +2. **ID 不变**: 更新不会改变 Webhook ID +3. **立即生效**: 更新后立即生效,除非停用 Webhook +4. **测试验证**: 建议更新后测试 Webhook 是否正常工作 +5. **权限要求**: 需要仓库管理员权限 + +## 常见使用场景 + +### 场景1: 迁移 Webhook 到新服务器 +```bash +# 更新 Webhook URL 到新服务器 +gitlink-cli webhook +update --id 456 --url https://new-server.example.com/webhook +# 测试新地址 +gitlink-cli webhook +test --id 456 +``` + +### 场景2: 调整事件监听 +```bash +# 原来只监听 push,现在增加 PR 监听 +gitlink-cli webhook +update --id 456 --events push,pull_request +``` + +### 场景3: 安全密钥轮换 +```bash +# 定期更新密钥提高安全性 +NEW_SECRET=$(openssl rand -hex 32) +gitlink-cli webhook +update --id 456 --secret "$NEW_SECRET" +# 更新接收服务器的密钥配置 +# 然后测试 +gitlink-cli webhook +test --id 456 +``` + +### 场景4: 临时维护 +```bash +# 临时停用 Webhook +gitlink-cli webhook +update --id 456 --active false --description "Maintenance in progress" + +# 维护完成后重新激活 +gitlink-cli webhook +update --id 456 --active true --description "Production webhook" +``` + +## 相关命令 + +- `webhook +list` - 列出所有 Webhook +- `webhook +create` - 创建新 Webhook +- `webhook +info` - 查看 Webhook 详情 +- `webhook +test` - 测试 Webhook diff --git a/skills/gitlink-wiki/SKILL.md b/skills/gitlink-wiki/SKILL.md new file mode 100644 index 0000000..4fc4306 --- /dev/null +++ b/skills/gitlink-wiki/SKILL.md @@ -0,0 +1,252 @@ +--- +name: gitlink-wiki +version: 1.0.0 +description: "Wiki 页面管理:列出、查看、创建、更新、删除 Wiki 页面。当用户需要管理项目 Wiki 文档时触发。" +metadata: + requires: + bins: ["gitlink-cli"] + cliHelp: "gitlink-cli wiki --help" +--- + +# gitlink-wiki(Wiki 页面操作) + +**CRITICAL — 开始前必须先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md),其中包含认证、权限处理和 API 注意事项。** +**CRITICAL — 所有 Shortcuts 在执行写入/删除操作前,务必先确认用户意图。** +**CRITICAL — GitLink 操作只能用 `gitlink-cli`。禁止用 `gh`(GitHub CLI)操作 GitLink 资源。`gh` 仅适用于 GitHub 平台。** + +> **前置条件:** 先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md) 了解认证和全局参数。 + +## 功能概述 + +GitLink Wiki 提供项目文档协作功能,支持 Markdown 格式的页面创建、编辑和管理。Wiki 功能通过 GitLink Gateway API (`https://gateway.gitlink.org.cn`) 提供,与核心 GitLink API 使用不同的 Base URL。 + +## Shortcuts + +| Shortcut | 说明 | 需要认证 | +|----------|------|----------| +| `wiki +list` | 列出所有 Wiki 页面 | 否(公开项目) | +| `wiki +view` | 查看 Wiki 页面内容 | 否(公开项目) | +| `wiki +create` | 创建 Wiki 页面 | 是 | +| `wiki +update` | 更新 Wiki 页面 | 是 | +| `wiki +delete` | 删除 Wiki 页面 | 是 | + +## 使用示例 + +```bash +# 列出所有 Wiki 页面 +gitlink-cli wiki +list --owner Gitlink --repo forgeplus + +# 查看 Wiki 页面 +gitlink-cli wiki +view --title "Home" + +# 创建 Wiki 页面(使用 --content 提供内容) +gitlink-cli wiki +create --title "API Reference" --content "# API Reference\n\n..." + +# 创建 Wiki 页面(从文件读取) +gitlink-cli wiki +create --title "Getting Started" --file README.md + +# 更新 Wiki 页面(覆盖整个内容) +gitlink-cli wiki +update --title "Home" --cover "# Updated content" + +# 更新 Wiki 页面(追加内容) +gitlink-cli wiki +update --title "Home" --add "\n\n## New Section\n\nAdditional content" + +# 删除 Wiki 页面 +gitlink-cli wiki +delete --title "Old Page" +``` + +## Wiki 内容编码 + +所有 Wiki 内容都会自动进行 **Base64 编码**: + +- **创建页面**:`--content` 或 `--file` 提供的内容会自动 Base64 编码 +- **更新页面**:`--cover` 或 `--add` 提供的内容会自动 Base64 编码 +- **查看页面**:返回的 `content_base64` 字段需要解码,CLI 会自动提供 `content_decoded` 字段 + +**无需手动编码/解码** — CLI 自动处理。 + +## 更新模式 + +`wiki +update` 支持两种更新模式: + +### 1. 覆盖模式 (`--cover`) +完全替换页面内容: + +```bash +gitlink-cli wiki +update --title "Home" --cover "# New Content" +``` + +### 2. 追加模式 (`--add`) +在现有内容基础上追加: + +```bash +gitlink-cli wiki +update --title "Home" --add "\n\n## Additional Section" +``` + +**工作原理**: +1. CLI 先获取当前页面内容 +2. 将新内容追加到现有内容后 +3. 提交更新后的完整内容 + +### 3. 重命名 + 更新 +```bash +# 将 "Old-Title" 重命名为 "New-Title" 并更新内容 +gitlink-cli wiki +update --page "Old-Title" --title "New-Title" --cover "Updated content" +``` + +## 参数说明 + +### 通用参数 + +| 参数 | 说明 | +|------|------| +| `--owner` | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 仓库名称(自动从 git remote 解析) | +| `--format` | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 开启调试输出 | + +### Wiki 专用参数 + +| 参数 | Short | 说明 | 适用于 | +|------|-------|------|--------| +| `--title` | `-t` | Wiki 页面标题 | `+view`, `+create`, `+update`, `+delete` | +| `--content` | `-c` | Wiki 页面内容(纯文本) | `+create` | +| `--file` | `-f` | 从文件读取内容 | `+create`, `+update` | +| `--page` | `-p` | 当前页面标题(用于查找和重命名) | `+update` | +| `--cover` | `-c` | 覆盖整个页面内容 | `+update` | +| `--add` | `-a` | 追加内容到现有页面 | `+update` | +| `--message` | `-m` | 提交消息 | `+create`, `+update` | + +## API 架构 + +### Base URL 差异 + +**重要**:Wiki 功能使用不同的 API Base URL: + +| 模块 | Base URL | +|------|----------| +| 核心 API (repo, issue, pr) | `https://www.gitlink.org.cn/api` | +| Wiki API | `https://gateway.gitlink.org.cn/api` | + +### Gateway API 响应格式 + +Wiki API 返回的响应格式需要特殊处理: + +```json +{ + "code": 200, + "msg": "success", + "data": { ... } +} +``` + +CLI 自动解析 Gateway 响应并提取 `data` 字段。 + +## 项目 ID 解析 + +Wiki 操作需要 `project_id`(数据库内部 ID),而不仅仅是 `owner/repo`。 + +**CLI 自动处理**: +1. 首先调用 `/api/:owner/:repo/detail` 获取 `project_id` +2. 使用 `project_id` 调用 Wiki Gateway API +3. 缓存 `project_id` 避免重复请求 + +**无需手动获取 project_id** — CLI 自动完成。 + +## 常见问题 + +### Q: 为什么 Wiki API 返回 404? + +**A:** 可能原因: +1. 页面标题不区分大小写,但必须完全匹配 +2. 项目没有启用 Wiki 功能 +3. 权限不足(私有项目需要认证) + +### Q: 更新操作失败怎么办? + +**A:** 检查: +1. `--title` 是否指定了正确的目标页面标题 +2. 如果是重命名,`--page` 是否指定了当前页面标题 +3. 是否有足够的权限修改 Wiki + +### Q: 如何创建多级 Wiki 页面? + +**A:** GitLink Wiki 不支持真正的目录结构,但可以通过命名约定模拟: +``` +"API/Authentication" # 使用斜杠 +"API/Authorization" # 模拟层级 +"Getting-Started" # 使用连字符 +``` + +### Q: 支持 Markdown 哪些语法? + +**A:** GitLink Wiki 支持 CommonMark 标准的 Markdown,包括: +- 标题 (`#`, `##`, `###`) +- 列表(有序、无序) +- 代码块(```) +- 链接 (`[text](url)`) +- 图片 (`![alt](url)`) +- 表格 +- 粗体、斜体 + +### Q: 删除操作为什么不返回确认信息? + +**A:** GitLink Wiki Gateway API 的删除端点可能返回成功或不返回信息。CLI 使用"获取页面内容"验证删除是否成功: +- 如果页面已不存在,删除成功 +- 如果页面仍存在,返回删除错误 + +## AI Agent 使用指南 + +### 推荐工作流 + +当用户请求"创建项目文档"时: + +1. **确认**项目 Wiki 需求(页面标题、内容) +2. **检查**是否需要创建多个页面 +3. **执行** `wiki +create` 创建页面 +4. **报告**创建结果和页面访问链接 + +当用户请求"更新文档"时: + +1. **获取**当前页面内容 (`wiki +view`) +2. **确认**更新方式(覆盖 vs 追加) +3. **执行** `wiki +update` +4. **报告**更新结果 + +### 错误处理 + +遇到以下错误时的建议: + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `404 Not Found` | 页面不存在 | 使用 `wiki +list` 查看可用页面 | +| `403 Forbidden` | 权限不足 | 引导用户登录 (`gitlink-cli auth login`) | +| `project_id not found` | 项目不存在或无权限 | 检查 `--owner` 和 `--repo` 是否正确 | +| `failed to encode/decode` | Base64 编解码问题 | 检查内容是否为有效 UTF-8 文本 | + +## Raw API 补充 + +```bash +# 直接调用 Gateway API(不推荐,优先使用 Shortcuts) +curl -X GET "https://gateway.gitlink.org.cn/api/wiki/open/wikiPages?owner=Gitlink&repo=forgeplus&projectId=123" + +# 创建 Wiki 页面(需要手动 Base64 编码) +curl -X POST "https://gateway.gitlink.org.cn/api/wiki/open/createWiki" \ + -H "Authorization: Bearer $TOKEN" \ + -d '{"owner":"Gitlink","repo":"forgeplus","projectId":123,"pageName":"Test","title":"Test","content_base64":"..."}' +``` + +## 参考文档 + +- [wiki +list](references/wiki-list.md) — 列出 Wiki 页面 +- [wiki +view](references/wiki-view.md) — 查看 Wiki 页面 +- [wiki +create](references/wiki-create.md) — 创建 Wiki 页面 +- [wiki +update](references/wiki-update.md) — 更新 Wiki 页面 +- [wiki +delete](references/wiki-delete.md) — 删除 Wiki 页面 +- [完整工作流](examples/wiki-workflow.md) — 实战示例 + +## 相关链接 + +- [gitlink-shared](../gitlink-shared/SKILL.md) — 认证、全局参数、安全规则 +- [gitlink-repo](../gitlink-repo/SKILL.md) — 仓库管理 +- [GitLink Wiki 帮助](https://help.gitlink.org.cn/) diff --git a/skills/gitlink-wiki/examples/wiki-workflow.md b/skills/gitlink-wiki/examples/wiki-workflow.md new file mode 100644 index 0000000..18138f7 --- /dev/null +++ b/skills/gitlink-wiki/examples/wiki-workflow.md @@ -0,0 +1,959 @@ +# Wiki 工作流示例 + +本文档提供了使用 `gitlink-cli wiki` 命令的完整工作流示例,涵盖从简单到复杂的各种场景。 + +## 目录 + +- [基础工作流](#基础工作流) +- [项目文档初始化](#项目文档初始化) +- [文档维护工作流](#文档维护工作流) +- [批量操作](#批量操作) +- [AI Agent 集成](#ai-agent-集成) +- [故障排除](#故障排除) + +--- + +## 基础工作流 + +### 工作流 1: 创建单个 Wiki 页面 + +**场景**: 为项目创建首页 + +```bash +#!/bin/bash +# 1. 创建首页 +gitlink-cli wiki +create --title "Home" --content '# Project Home + +## Overview +This project is a CLI tool for GitLink platform. + +## Features +- Repository management +- Issue tracking +- Pull requests + +## Documentation +- [Getting Started](Getting-Started) +- [API Reference](API-Reference) +- [Contributing](Contributing) + +## Support +- [FAQ](FAQ) +- [Contact Us](Contact-Us)' + +# 2. 验证创建结果 +gitlink-cli wiki +view --title "Home" + +# 3. 列出所有页面 +gitlink-cli wiki +list +``` + +**预期结果**: +- 创建了标题为 "Home" 的 Wiki 页面 +- 页面包含导航链接和项目概述 +- 可通过 `wiki +list` 和 `wiki +view` 验证 + +--- + +## 项目文档初始化 + +### 工作流 2: 创建完整项目文档结构 + +**场景**: 为新项目创建完整的 Wiki 文档体系 + +```bash +#!/bin/bash +# init-project-wiki.sh + +set -e # 遇到错误立即退出 + +echo "=== Initializing Project Wiki ===" + +# 1. 创建首页 +echo "Creating Home page..." +gitlink-cli wiki +create --title "Home" --content '# Project Documentation + +Welcome to the project documentation! + +## Quick Links +- 📚 [Getting Started](Getting-Started) - New user guide +- 📖 [API Reference](API-Reference) - API documentation +- 🤝 [Contributing](Contributing) - Contribution guide +- ❓ [FAQ](FAQ) - Frequently asked questions + +## Overview +This project provides a comprehensive CLI tool for GitLink platform management. + +## Status +- Version: 1.0.0 +- License: MIT +- Support: See [Contact Us](Contact-Us)' + +# 2. 创建入门指南 +echo "Creating Getting Started guide..." +gitlink-cli wiki +create --title "Getting-Started" --content '# Getting Started + +## Installation + +### Prerequisites +- Node.js 14+ +- GitLink account + +### Install via npm +\`\`\`bash +npm install -g gitlink-cli +\`\`\` + +### Install from source +\`\`\`bash +git clone https://www.gitlink.org.cn/Gitlink/gitlink-cli.git +cd gitlink-cli +make install +\`\`\` + +## Configuration + +### Initialize config +\`\`\`bash +gitlink-cli config init +\`\`\` + +### Login +\`\`\`bash +gitlink-cli auth login +\`\`\` + +## Verify Installation +\`\`\`bash +gitlink-cli --version +gitlink-cli user +me +\`\`\`' + +# 3. 创建 API 文档 +echo "Creating API Reference..." +gitlink-cli wiki +create --title "API-Reference" --content '# API Reference + +## Repository Operations + +### List repositories +\`\`\`bash +gitlink-cli repo +list +\`\`\` + +### Create repository +\`\`\`bash +gitlink-cli repo +create -n my-project -d "Project description" +\`\`\` + +## Issue Operations + +### List issues +\`\`\`bash +gitlink-cli issue +list --owner user --repo project +\`\`\` + +### Create issue +\`\`\`bash +gitlink-cli issue +create -t "Bug title" -b "Bug description" +\`\`\` + +## Pull Request Operations + +### List PRs +\`\`\`bash +gitlink-cli pr +list --owner user --repo project +\`\`\` + +### Create PR +\`\`\`bash +gitlink-cli pr +create --head feature --base main -t "Feature title" +\`\`\`' + +# 4. 创建贡献指南 +echo "Creating Contributing guide..." +gitlink-cli wiki +create --title "Contributing" --content '# Contributing + +Thank you for your interest in contributing! + +## How to Contribute + +### Report Bugs +Create an issue with the bug report template. + +### Submit Changes +1. Fork the repository +2. Create a feature branch +3. Make your changes +4. Submit a pull request + +## Development Workflow + +### Setup Development Environment +\`\`\`bash +git clone https://www.gitlink.org.cn/YOUR_USERNAME/gitlink-cli.git +cd gitlink-cli +make install +\`\`\` + +### Run Tests +\`\`\`bash +make test +\`\`\` + +### Code Style +- Follow Go conventions +- Add tests for new features +- Update documentation + +## Pull Request Guidelines + +### PR Title Format +- \`feat: add new feature\` +- \`fix: fix bug description\` +- \`docs: update documentation\` + +### PR Description +Include: +- Problem statement +- Solution approach +- Testing performed +- Related issues' + +# 5. 创建 FAQ +echo "Creating FAQ..." +gitlink-cli wiki +create --title "FAQ" --content '# Frequently Asked Questions + +## General Questions + +### Q: What is gitlink-cli? +A: GitLink CLI is a command-line tool for managing GitLink platform resources. + +### Q: How do I install gitlink-cli? +A: Run \`npm install -g gitlink-cli\` or build from source. + +## Authentication + +### Q: How do I authenticate? +A: Run \`gitlink-cli auth login\` and provide your credentials. + +### Q: How long does the token last? +A: Tokens expire after 7 days. Re-authenticate when expired. + +## Troubleshooting + +### Q: Command not found +A: Ensure npm global bin is in your PATH: \`export PATH=\$PATH:\$(npm config get prefix)/bin\` + +### Q: Permission denied +A: Run \`gitlink-cli auth login\` to re-authenticate. + +## More Help +- See [Getting Started](Getting-Started) +- Check [API Reference](API-Reference) +- Contact: [Contact Us](Contact-Us)' + +# 6. 创建联系我们页面 +echo "Creating Contact Us page..." +gitlink-cli wiki +create --title "Contact-Us" --content '# Contact Us + +## Get Help + +### Documentation +- [Getting Started](Getting-Started) +- [API Reference](API-Reference) +- [FAQ](FAQ) + +### Community +- Forum: [GitLink Forum](https://forum.gitlink.org.cn) +- Chat: [Gitter Channel](https://gitter.im/gitlink-cli) + +### Report Issues +- Bug Reports: [Issue Tracker](https://www.gitlink.org.cn/Gitlink/gitlink-cli/issues) +- Feature Requests: [Issue Tracker](https://www.gitlink.org.cn/Gitlink/gitlink-cli/issues) + +## Development Team + +### Maintainers +- @maintainer1 - Project lead +- @maintainer2 - Core development + +### Contributors +See [CONTRIBUTORS.md](https://www.gitlink.org.cn/Gitlink/gitlink-cli/blob/master/CONTRIBUTORS.md) + +## License +This project is licensed under the MulanPSL-2.0 License. + +## Acknowledgments +Thanks to all contributors who have helped improve this project!' + +echo "=== Wiki Initialization Complete ===" +echo "Created 6 documentation pages:" +gitlink-cli wiki +list +``` + +**关键特性**: +- ✅ 创建了完整的文档结构 +- ✅ 页面之间有交叉引用链接 +- ✅ 包含代码示例和命令 +- ✅ 覆盖了项目的所有主要方面 + +--- + +## 文档维护工作流 + +### 工作流 3: 更新文档内容 + +**场景**: 文档需要定期更新以反映项目变化 + +```bash +#!/bin/bash +# update-documentation.sh + +page_title="API-Reference" +backup_file="wiki-backup-$(date '+%Y%m%d-%H%M%S').md" + +echo "=== Safe Wiki Update Workflow ===" + +# 1. 备份当前内容 +echo "Step 1: Backing up current content..." +gitlink-cli wiki +view --title "$page_title" --format json | \ + jq -r ".data.content_decoded" > "$backup_file" +echo "✓ Backup saved: $backup_file" + +# 2. 显示当前内容预览 +echo "" +echo "Step 2: Current content preview:" +head -n 10 "$backup_file" +echo "..." + +# 3. 编辑内容(使用临时文件) +temp_file="temp-wiki-update.md" +cp "$backup_file" "$temp_file" + +echo "" +echo "Step 3: Edit the content in: $temp_file" +echo "Press Enter when done editing..." +read + +# 4. 确认更新 +echo "" +echo "Step 4: Review changes:" +echo "--- Old content (first 5 lines) ---" +head -n 5 "$backup_file" +echo "--- New content (first 5 lines) ---" +head -n 5 "$temp_file" +echo "---" + +read -p "Apply changes? (y/N) " -n 1 -r +echo + +if [[ $REPLY =~ ^[Yy]$ ]]; then + # 5. 执行更新 + echo "Step 5: Applying update..." + gitlink-cli wiki +update --title "$page_title" --file "$temp_file" + + # 6. 验证结果 + echo "Step 6: Verifying update..." + gitlink-cli wiki +view --title "$page_title" --format json | \ + jq -r ".data.content_decoded" > "updated-content.md" + + if diff -q "$temp_file" "updated-content.md" >/dev/null; then + echo "✓ Update successful!" + rm "$temp_file" "updated-content.md" + else + echo "✗ Update verification failed!" + echo "Backup available at: $backup_file" + fi +else + echo "✗ Update cancelled." + echo "Backup available at: $backup_file" + rm "$temp_file" +fi +``` + +--- + +### 工作流 4: 追加更新日志 + +**场景**: 在文档末尾追加更新日志 + +```bash +#!/bin/bash +# append-changelog.sh + +page_title="Home" +changelog_content=" + +--- + +## Changelog + +### v$(date '+%Y.%m.%d') +- Updated documentation structure +- Added new examples +- Fixed typos and errors +- Improved API references" + +echo "=== Appending Changelog to $page_title ===" + +# 1. 查看当前末尾内容 +echo "Current page ending:" +gitlink-cli wiki +view --title "$page_title" --format json | \ + jq -r ".data.content_decoded" | tail -n 5 + +# 2. 确认追加 +echo "" +echo "Content to append:" +echo "$changelog_content" + +read -p "Append changelog? (y/N) " -n 1 -r +echo + +if [[ $REPLY =~ ^[Yy]$ ]]; then + # 3. 追加内容 + gitlink-cli wiki +update --title "$page_title" --add "$changelog_content" + echo "✓ Changelog appended successfully!" + + # 4. 验证 + echo "" + echo "Updated page ending:" + gitlink-cli wiki +view --title "$page_title" --format json | \ + jq -r ".data.content_decoded" | tail -n 10 +else + echo "✗ Append cancelled." +fi +``` + +--- + +## 批量操作 + +### 工作流 5: 从本地目录批量导入 Wiki + +**场景**: 将本地的 Markdown 文档批量导入到 Wiki + +```bash +#!/bin/bash +# batch-import-wiki.sh + +wiki_docs_dir="./wiki-docs" +backup_dir="wiki-import-backup-$(date '+%Y%m%d-%H%M%S')" + +echo "=== Batch Wiki Import ===" + +# 1. 检查目录 +if [ ! -d "$wiki_docs_dir" ]; then + echo "Error: Directory '$wiki_docs_dir' not found." + echo "Please create it and add your Markdown files." + exit 1 +fi + +# 2. 创建备份目录 +mkdir -p "$backup_dir" + +# 3. 统计文件 +md_files=("$wiki_docs_dir"/*.md) +total_files=${#md_files[@]} + +echo "Found $total_files Markdown files in '$wiki_docs_dir'" + +# 4. 遍历导入 +success_count=0 +skip_count=0 +error_count=0 + +for mdfile in "${md_files[@]}"; do + # 从文件名提取标题(去掉 .md 后缀) + filename=$(basename "$mdfile") + title="${filename%.md}" + + echo "" + echo "Processing: $filename" + + # 检查页面是否已存在 + if gitlink-cli wiki +view --title "$title" >/dev/null 2>&1; then + echo " ⚠️ Page '$title' already exists. Skipping." + ((skip_count++)) + + # 备份现有页面 + gitlink-cli wiki +view --title "$title" --format json | \ + jq -r ".data.content_decoded" > "$backup_dir/$filename" + continue + fi + + # 创建新页面 + if gitlink-cli wiki +create --title "$title" --file "$mdfile" 2>/dev/null; then + echo " ✓ Created: $title" + ((success_count++)) + else + echo " ✗ Failed: $title" + ((error_count++)) + + # 失败时备份文件 + cp "$mdfile" "$backup_dir/" + fi +done + +# 5. 显示统计 +echo "" +echo "=== Import Summary ===" +echo "Total files: $total_files" +echo "✓ Created: $success_count" +echo "⚠️ Skipped: $skip_count (already exists)" +echo "✗ Failed: $error_count" + +if [ $error_count -gt 0 ]; then + echo "" + echo "Failed files backed up to: $backup_dir" +fi + +# 6. 列出当前所有页面 +echo "" +echo "Current Wiki pages:" +gitlink-cli wiki +list +``` + +--- + +### 工作流 6: 批量导出 Wiki 为本地文件 + +**场景**: 将所有 Wiki 页面导出为本地 Markdown 文件 + +```bash +#!/bin/bash +# batch-export-wiki.sh + +export_dir="wiki-export-$(date '+%Y%m%d-%H%M%S')" + +echo "=== Batch Wiki Export ===" + +# 1. 创建导出目录 +mkdir -p "$export_dir" +echo "Export directory: $export_dir" + +# 2. 获取所有页面标题 +titles=$(gitlink-cli wiki +list --format json | jq -r '.data[].title') +total_titles=$(echo "$titles" | wc -l) + +echo "Found $total_titles Wiki pages" + +# 3. 遍历导出 +success_count=0 +error_count=0 + +for title in $titles; do + # 清理文件名(替换特殊字符) + filename=$(echo "$title" | sed 's/[^a-zA-Z0-9_-]/_/g').md + + echo "Exporting: $title -> $filename" + + # 导出页面内容 + if gitlink-cli wiki +view --title "$title" --format json | \ + jq -r '.data.content_decoded' > "$export_dir/$filename" 2>/dev/null; then + echo " ✓ Exported: $filename" + ((success_count++)) + else + echo " ✗ Failed: $title" + ((error_count++)) + fi +done + +# 4. 显示统计 +echo "" +echo "=== Export Summary ===" +echo "Total pages: $total_titles" +echo "✓ Exported: $success_count" +echo "✗ Failed: $error_count" + +# 5. 创建索引文件 +echo "# Wiki Export Index" > "$export_dir/README.md" +echo "" >> "$export_dir/README.md" +echo "Export Date: $(date)" >> "$export_dir/README.md" +echo "" >> "$export_dir/README.md" +echo "## Pages" >> "$export_dir/README.md" +echo "" >> "$export_dir/README.md" + +for title in $titles; do + filename=$(echo "$title" | sed 's/[^a-zA-Z0-9_-]/_/g').md + echo "- [$title]($filename)" >> "$export_dir/README.md" +done + +echo "" +echo "✓ Index created: $export_dir/README.md" +echo "Export completed: $export_dir" +``` + +--- + +### 工作流 7: 批量重命名页面 + +**场景**: 统一 Wiki 页面命名规范 + +```bash +#!/bin/bash +# batch-rename-wiki.sh + +# 定义重命名规则(旧标题 -> 新标题) +declare -A rename_rules=( + ["api"]="API-Reference" + ["getting started"]="Getting-Started" + ["user guide"]="User-Guide" + ["faq"]="FAQ" + ["home"]="Home" +) + +echo "=== Batch Wiki Rename ===" + +# 1. 显示重命名计划 +echo "Planned renames:" +for old_title in "${!rename_rules[@]}"; do + new_title="${rename_rules[$old_title]}" + echo " '$old_title' -> '$new_title'" +done + +# 2. 确认执行 +read -p "Proceed with renaming? (yes/NO) " -r +echo + +if [[ ! "$REPLY" == "yes" ]]; then + echo "✗ Renaming cancelled." + exit 0 +fi + +# 3. 执行重命名 +success_count=0 +skip_count=0 +error_count=0 + +for old_title in "${!rename_rules[@]}"; do + new_title="${rename_rules[$old_title]}" + + echo "" + echo "Renaming: '$old_title' -> '$new_title'" + + # 检查旧页面是否存在 + if ! gitlink-cli wiki +view --title "$old_title" >/dev/null 2>&1; then + echo " ⚠️ Old page '$old_title' not found. Skipping." + ((skip_count++)) + continue + fi + + # 检查新页面是否已存在 + if gitlink-cli wiki +view --title "$new_title" >/dev/null 2>&1; then + echo " ⚠️ Target page '$new_title' already exists. Skipping." + ((skip_count++)) + continue + fi + + # 执行重命名 + if gitlink-cli wiki +update --page "$old_title" --title "$new_title" 2>/dev/null; then + echo " ✓ Renamed successfully" + ((success_count++)) + else + echo " ✗ Rename failed" + ((error_count++)) + fi +done + +# 4. 显示统计 +echo "" +echo "=== Rename Summary ===" +echo "Total planned: ${#rename_rules[@]}" +echo "✓ Renamed: $success_count" +echo "⚠️ Skipped: $skip_count" +echo "✗ Failed: $error_count" + +# 5. 列出当前所有页面 +echo "" +echo "Current Wiki pages:" +gitlink-cli wiki +list +``` + +--- + +## AI Agent 集成 + +### 工作流 8: AI Agent 自动文档管理 + +**场景**: AI Agent 自动维护项目文档 + +```python +#!/usr/bin/env python3 +# ai_wiki_manager.py - AI Agent Wiki 管理示例 + +import subprocess +import json +import os +from datetime import datetime + +class WikiManager: + """GitLink Wiki 管理器 - 为 AI Agent 设计""" + + def __init__(self, owner, repo): + self.owner = owner + self.repo = repo + self.base_cmd = ["gitlink-cli", "--owner", owner, "--repo", repo] + + def run_command(self, command): + """执行 gitlink-cli 命令并返回结果""" + try: + full_cmd = self.base_cmd + command + result = subprocess.run( + full_cmd, + capture_output=True, + text=True, + check=True + ) + return result.stdout + except subprocess.CalledProcessError as e: + print(f"Command failed: {' '.join(full_cmd)}") + print(f"Error: {e.stderr}") + return None + + def list_pages(self): + """列出所有 Wiki 页面""" + output = self.run_command(["wiki", "+list", "--format", "json"]) + if output: + data = json.loads(output) + return data.get("data", []) + return [] + + def get_page_content(self, title): + """获取指定页面的内容""" + output = self.run_command( + ["wiki", "+view", "--title", title, "--format", "json"] + ) + if output: + data = json.loads(output) + return data.get("data", {}).get("content_decoded", "") + return None + + def create_page(self, title, content): + """创建新页面""" + # 创建临时文件 + temp_file = f"/tmp/wiki_{title}.md" + with open(temp_file, 'w') as f: + f.write(content) + + # 从文件创建 + result = self.run_command( + ["wiki", "+create", "--title", title, "--file", temp_file] + ) + + # 清理临时文件 + os.remove(temp_file) + return result is not None + + def update_page(self, title, content, mode="cover"): + """更新页面内容 + + Args: + title: 页面标题 + content: 新内容 + mode: 更新模式 ("cover" 或 "add") + """ + temp_file = f"/tmp/wiki_update_{title}.md" + with open(temp_file, 'w') as f: + f.write(content) + + if mode == "cover": + result = self.run_command( + ["wiki", "+update", "--title", title, "--file", temp_file] + ) + else: # add mode + result = self.run_command( + ["wiki", "+update", "--title", title, "--add", "", + "--file", temp_file] + ) + + os.remove(temp_file) + return result is not None + + def delete_page(self, title): + """删除页面""" + result = self.run_command(["wiki", "+delete", "--title", title]) + return result is not None + + def search_in_pages(self, keyword): + """在所有页面中搜索关键词""" + pages = self.list_pages() + results = [] + + for page in pages: + title = page.get("title", "") + content = self.get_page_content(title) + + if content and keyword.lower() in content.lower(): + results.append({ + "title": title, + "url": page.get("sub_url", ""), + "preview": self.get_preview(content, keyword) + }) + + return results + + def get_preview(self, content, keyword, context=50): + """获取关键词周围的预览文本""" + index = content.lower().find(keyword.lower()) + if index == -1: + return "" + + start = max(0, index - context) + end = min(len(content), index + len(keyword) + context) + return content[start:end] + + +# AI Agent 使用示例 +def ai_agent_example(): + """AI Agent 自动维护文档的示例""" + + # 初始化 Wiki 管理器 + wiki = WikiManager("Gitlink", "forgeplus") + + print("=== AI Agent Wiki Manager ===") + + # 1. 检查文档完整性 + print("\n1. Checking documentation completeness...") + required_pages = ["Home", "Getting-Started", "API-Reference", "FAQ"] + current_pages = [p.get("title") for p in wiki.list_pages()] + + missing_pages = set(required_pages) - set(current_pages) + if missing_pages: + print(f" ⚠️ Missing pages: {missing_pages}") + # AI Agent 可以自动创建缺失的页面 + else: + print(" ✓ All required pages exist") + + # 2. 检查过时内容 + print("\n2. Checking for outdated content...") + outdated_keywords = ["version 0.9", "deprecated", "coming soon"] + for keyword in outdated_keywords: + results = wiki.search_in_pages(keyword) + if results: + print(f" ⚠️ Found '{keyword}' in:") + for result in results: + print(f" - {result['title']}") + # AI Agent 可以标记这些页面需要更新 + + # 3. 自动更新版本信息 + print("\n3. Auto-updating version information...") + home_content = wiki.get_page_content("Home") + if home_content and "Version: 1.0.0" in home_content: + new_version = "1.0.1" + updated_content = home_content.replace("1.0.0", new_version) + if wiki.update_page("Home", updated_content, "cover"): + print(f" ✓ Updated version to {new_version}") + + # 4. 生成统计报告 + print("\n4. Generating statistics...") + pages = wiki.list_pages() + total_pages = len(pages) + + print(f" Total pages: {total_pages}") + print(f" Last updated: {datetime.now().strftime('%Y-%m-%d')}") + + # 计算每个页面的字符数 + for page in pages: + title = page['title'] + content = wiki.get_page_content(title) + if content: + char_count = len(content) + print(f" - {title}: {char_count} characters") + + +if __name__ == "__main__": + ai_agent_example() +``` + +--- + +## 故障排除 + +### 工作流 9: 常见问题诊断 + +```bash +#!/bin/bash +# wiki-diagnose.sh - Wiki 问题诊断工具 + +echo "=== Wiki Diagnostic Tool ===" + +# 1. 检查认证状态 +echo "1. Checking authentication..." +if gitlink-cli auth status 2>/dev/null | grep -q "Logged in"; then + echo " ✓ Authentication OK" +else + echo " ✗ Authentication failed" + echo " Solution: Run 'gitlink-cli auth login'" + exit 1 +fi + +# 2. 检查网络连接 +echo "2. Checking network connectivity..." +if curl -s -o /dev/null -w "%{http_code}" https://www.gitlink.org.cn | grep -q "200\|301\|302"; then + echo " ✓ Network connectivity OK" +else + echo " ✗ Network connectivity failed" + echo " Solution: Check your internet connection" +fi + +# 3. 检查 Gateway API 可用性 +echo "3. Checking Gateway API..." +if curl -s -o /dev/null -w "%{http_code}" https://gateway.gitlink.org.cn/api | grep -q "200\|301\|302"; then + echo " ✓ Gateway API available" +else + echo " ✗ Gateway API unavailable" + echo " Solution: Gateway API may be down, try again later" +fi + +# 4. 检查项目权限 +echo "4. Checking project permissions..." +if gitlink-cli repo +info >/dev/null 2>&1; then + echo " ✓ Project access OK" +else + echo " ✗ Project access failed" + echo " Solution: Check if --owner and --repo are correct" +fi + +# 5. 测试 Wiki 功能 +echo "5. Testing Wiki functionality..." +page_count=$(gitlink-cli wiki +list --format json 2>/dev/null | jq '.meta.total_count // 0') +if [ "$page_count" -ge 0 ]; then + echo " ✓ Wiki功能正常 (当前页面数: $page_count)" +else + echo " ✗ Wiki功能异常" + echo " Solution: Wiki may not be enabled for this project" +fi + +# 6. 显示诊断总结 +echo "" +echo "=== Diagnostic Summary ===" +echo "如果以上检查都通过,Wiki 功能应该可以正常使用。" +echo "如果仍有问题,请检查:" +echo " 1. 页面标题是否正确(区分大小写)" +echo " 2. 是否有足够的权限操作 Wiki" +echo " 3. 网络连接是否稳定" +echo " 4. GitLink 平台是否正常运行" +``` + +--- + +## 总结 + +本文档提供了从基础到高级的 Wiki 工作流示例,涵盖: + +- ✅ **基础操作**: 创建、查看、更新、删除 +- ✅ **项目初始化**: 完整的文档结构建立 +- ✅ **文档维护**: 安全的更新和追加工作流 +- ✅ **批量处理**: 导入、导出、重命名批量操作 +- ✅ **AI 集成**: Python 实现的自动化管理 +- ✅ **故障排除**: 诊断和问题解决 + +这些工作流可以直接使用或根据具体需求调整。 + +## 相关文档 + +- [gitlink-wiki](../SKILL.md) — Wiki 功能总览 +- [wiki +list](../references/wiki-list.md) — 列出页面 +- [wiki +create](../references/wiki-create.md) — 创建页面 +- [wiki +update](../references/wiki-update.md) — 更新页面 +- [wiki +delete](../references/wiki-delete.md) — 删除页面 diff --git a/skills/gitlink-wiki/references/wiki-create.md b/skills/gitlink-wiki/references/wiki-create.md new file mode 100644 index 0000000..bc0b071 --- /dev/null +++ b/skills/gitlink-wiki/references/wiki-create.md @@ -0,0 +1,423 @@ +# wiki +create + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **⚠️ 写入操作** — 执行前必须确认用户意图。 + +创建新的 Wiki 页面。支持直接提供内容或从文件读取。 + +## 命令 + +```bash +# 创建简单页面(使用 --content) +gitlink-cli wiki +create --title "Home" --content "# Welcome\n\nThis is the home page." + +# 创建页面(从文件读取) +gitlink-cli wiki +create --title "API Reference" --file api.md + +# 创建页面并添加提交消息 +gitlink-cli wiki +create --title "Getting Started" \ + --content "# Getting Started\n\n..." \ + --message "Initial documentation" + +# 创建多行内容页面 +gitlink-cli wiki +create --title "Guide" --content "# User Guide + +## Installation +Run the following command: + +\`\`\`bash +npm install +\`\`\` + +## Usage +\`\`\`bash +npm start +\`\`\`" +``` + +## 参数 + +| 参数 | Short | 必填 | 说明 | +|------|-------|------|------| +| `--title` | `-t` | **是** | Wiki 页面标题 | +| `--content` | `-c` | **是*** | Wiki 页面内容(纯文本,与 `--file` 二选一) | +| `--file` | `-f` | **是*** | 从文件读取内容(与 `--content` 二选一) | +| `--message` | `-m` | 否 | 提交消息(可选) | +| `--owner` | | 否 | 仓库所有者(自动从 git remote 解析) | +| `--repo` | | 否 | 仓库名称(自动从 git remote 解析) | +| `--format` | | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | | 否 | 开启调试输出 | + +* `--content` 和 `--file` 必须指定其中一个 + +## 返回字段 + +### Table 格式 + +| 列名 | 说明 | +|------|------| +| `title` | 创建的页面标题 | +| `message` | 操作结果消息 | + +### JSON 格式 + +```json +{ + "ok": true, + "data": { + "title": "Home", + "message": "Wiki page created successfully" + } +} +``` + +## Workflow + +1. **Confirm** the page title and content with the user. +2. **Check** if the page already exists (optional, use `wiki +view`). +3. **Execute** `gitlink-cli wiki +create --title "" --content "<content>"`. +4. **Report** the creation result and page URL. + +> [!CAUTION] +> This is a **Write Operation** — confirm user intent before executing. + +## API + +``` +POST https://gateway.gitlink.org.cn/api/wiki/open/createWiki +Body: { + "owner": "...", + "repo": "...", + "projectId": 123, + "pageName": "<title>", + "title": "<title>", + "content_base64": "<base64-encoded-content>", + "message": "<optional-message>" +} +``` + +**工作流程**: +1. CLI 获取 `project_id` +2. 将内容 Base64 编码为 `content_base64` +3. 调用 Gateway API 创建页面 +4. 返回创建结果 + +## 使用场景 + +### 场景 1: 创建首页 + +当用户请求"创建项目首页"时: + +```bash +gitlink-cli wiki +create --title "Home" \ + --content "# Project Home + +## Overview +This project is a CLI tool for GitLink platform. + +## Features +- Repository management +- Issue tracking +- Pull requests + +## Getting Started +See the [Getting Started](Getting-Started) page." +``` + +### 场景 2: 从现有文件创建 + +```bash +# 从 README.md 创建 Wiki +gitlink-cli wiki +create --title "Home" --file README.md + +# 从多个文件创建多个页面 +gitlink-cli wiki +create --title "API Reference" --file docs/api.md +gitlink-cli wiki +create --title "User Guide" --file docs/guide.md +``` + +### 场景 3: 创建代码文档 + +```bash +gitlink-cli wiki +create --title "CLI Reference" --content "# CLI Commands + +## Repository Commands +\`\`\`bash +gitlink-cli repo +list +gitlink-cli repo +create -n my-project +\`\`\` + +## Issue Commands +\`\`\`bash +gitlink-cli issue +list +gitlink-cli issue +create -t \"Bug: ...\" +\`\`\`" +``` + +### 场景 4: 批量创建 Wiki 页面 + +```bash +#!/bin/bash +# 从 docs/ 目录批量创建 Wiki 页面 + +for mdfile in docs/*.md; do + # 从文件名提取标题(去掉 .md 后缀) + title=$(basename "$mdfile" .md) + + echo "Creating Wiki page: $title" + gitlink-cli wiki +create --title "$title" --file "$mdfile" +done +``` + +## 内容编码 + +### Base64 自动处理 + +**无需手动编码** — CLI 自动处理: + +```bash +# CLI 会自动将以下内容 Base64 编码 +gitlink-cli wiki +create --title "Test" --content "Hello, World!" + +# 等效于手动编码(不推荐) +gitlink-cli api POST "https://gateway.gitlink.org.cn/api/wiki/open/createWiki" \ + --body '{ + "owner": "...", + "repo": "...", + "projectId": 123, + "pageName": "Test", + "title": "Test", + "content_base64": "SGVsbG8sIFdvcmxkIQ==" + }' +``` + +### 多行内容处理 + +```bash +# 方法 1: 使用 \n 换行 +gitlink-cli wiki +create --title "Test" \ + --content "Line 1\nLine 2\nLine 3" + +# 方法 2: 使用 $'' 引号(支持 \n) +gitlink-cli wiki +create --title "Test" --content $'Line 1\nLine 2\nLine 3' + +# 方法 3: 从文件读取(推荐) +cat << 'EOF' > temp.md +Line 1 +Line 2 +Line 3 +EOF +gitlink-cli wiki +create --title "Test" --file temp.md +``` + +## 常见问题 + +### Q: 创建失败提示 "page already exists"? + +**A:** 页面标题已存在。解决方法: +```bash +# 查看现有页面 +gitlink-cli wiki +list + +# 使用不同的标题,或先删除现有页面 +gitlink-cli wiki +delete --title "Old Title" +gitlink-cli wiki +create --title "New Title" --content "..." +``` + +### Q: 内容显示格式错误? + +**A:** 确保: +1. Markdown 语法正确 +2. 使用 `\n` 表示换行(单行字符串) +3. 或从文件读取(保留原始格式) + +### Q: 如何创建包含代码块的页面? + +**A:** 使用正确的 Markdown 语法: +```bash +gitlink-cli wiki +create --title "Code Examples" \ + --content '# Code Examples + +## JavaScript +\`\`\`javascript +console.log("Hello"); +\`\`\` + +## Python +\`\`\`python +print("Hello") +\`\`\`' +``` + +### Q: 支持哪些 Markdown 语法? + +**A:** GitLink Wiki 支持: +- 标题 (`#`, `##`, `###`) +- 列表(有序、无序) +- 代码块(```) +- 链接 (`[text](url)`) +- 图片 (`![alt](url)`) +- 表格 +- 粗体、斜体、引用 + +### Q: 可以创建 HTML 内容吗? + +**A:** GitLink Wiki 主要支持 Markdown,部分 HTML 可能被过滤。建议使用标准 Markdown 语法。 + +## 错误处理 + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `required flag --title is missing` | 未指定标题 | 添加 `--title "Page Title"` | +| `--content or --file is required` | 未提供内容 | 添加 `--content "..."` 或 `--file file.md` | +| `failed to read file` | 文件不存在或无权限 | 检查文件路径和权限 | +| `page already exists` | 标题已存在 | 使用不同标题或先删除现有页面 | +| `401 Unauthorized` | 未登录或 Token 过期 | 运行 `gitlink-cli auth login` | +| `403 Forbidden` | 无权限创建 Wiki | 检查是否有项目写入权限 | + +## 最佳实践 + +### 1. 标题命名规范 + +```bash +# 推荐:使用连字符连接单词 +"Getting-Started" +"API-Reference" +"User-Guide" + +# 避免:空格和特殊字符 +"Getting Started" # 需要引号 +"API/Reference" # 斜杠可能被误解 +``` + +### 2. 内容模板 + +创建文档时使用标准模板: + +```bash +gitlink-cli wiki +create --title "Page Title" --content '# Page Title + +## Overview +Brief description of the page. + +## Details +Detailed content. + +## Examples +\`\`\`bash +Example code +\`\`\` + +## See Also +- [Related Page 1](Related-Page-1) +- [Related Page 2](Related-Page-2)' +``` + +### 3. 从文件创建 + +对于复杂内容,先创建文件再导入: + +```bash +# 1. 创建本地 Markdown 文件 +cat > home.md << 'EOF' +# Home + +Welcome to the project! +EOF + +# 2. 从文件创建 Wiki +gitlink-cli wiki +create --title "Home" --file home.md + +# 3. 清理临时文件 +rm home.md +``` + +### 4. 批量创建工作流 + +```bash +#!/bin/bash +# 批量创建项目文档 + +# 定义页面列表 +declare -A pages=( + ["Home"]="home.md" + ["Getting-Started"]="getting-started.md" + ["API-Reference"]="api.md" + ["FAQ"]="faq.md" +) + +# 遍历创建 +for title in "${!pages[@]}"; do + file="${pages[$title]}" + if [ -f "$file" ]; then + echo "Creating: $title from $file" + gitlink-cli wiki +create --title "$title" --file "$file" + else + echo "Warning: $file not found, skipping $title" + fi +done +``` + +## 完整示例 + +### 示例:创建完整项目 Wiki + +```bash +#!/bin/bash +# 为新项目创建完整的 Wiki 文档结构 + +# 1. 创建首页 +gitlink-cli wiki +create --title "Home" --content '# Project Home + +## Overview +This is a demonstration project for gitlink-cli Wiki. + +## Documentation +- [Getting Started](Getting-Started) +- [API Reference](API-Reference) +- [Contributing](Contributing) + +## Support +- [FAQ](FAQ) +- [Contact Us](Contact-Us)' + +# 2. 创建入门指南 +gitlink-cli wiki +create --title "Getting-Started" --content '# Getting Started + +## Installation +\`\`\`bash +npm install +\`\`\` + +## Configuration +\`\`\`bash +cp .env.example .env +\`\`\` + +## Running +\`\`\`bash +npm start +\`\`\`' + +# 3. 创建 API 文档 +gitlink-cli wiki +create --title "API-Reference" --content '# API Reference + +## Endpoints + +### GET /api/users +Get user information. + +### POST /api/issues +Create a new issue. + +## Examples +See the [Examples](Examples) page.' + +echo "Wiki documentation structure created successfully!" +``` + +## References + +- [gitlink-wiki](../SKILL.md) +- [wiki +update](wiki-update.md) — 更新 Wiki 页面 +- [wiki +delete](wiki-delete.md) — 删除 Wiki 页面 +- [gitlink-shared](../../gitlink-shared/SKILL.md) diff --git a/skills/gitlink-wiki/references/wiki-delete.md b/skills/gitlink-wiki/references/wiki-delete.md new file mode 100644 index 0000000..75f0109 --- /dev/null +++ b/skills/gitlink-wiki/references/wiki-delete.md @@ -0,0 +1,539 @@ +# wiki +delete + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **⚠️ 危险操作** — 删除操作**无法撤销**,执行前必须确认用户意图。 + +删除指定的 Wiki 页面。⚠️ **此操作不可逆!** + +## 命令 + +```bash +# 删除 Wiki 页面 +gitlink-cli wiki +delete --title "Old Page" + +# 删除指定仓库的 Wiki 页面 +gitlink-cli wiki +delete --owner Gitlink --repo forgeplus --title "Outdated" + +# 删除前先确认(推荐) +gitlink-cli wiki +view --title "Page to Delete" # 先查看内容 +gitlink-cli wiki +delete --title "Page to Delete" # 再删除 +``` + +## 参数 + +| 参数 | Short | 必填 | 说明 | +|------|-------|------|------| +| `--title` | `-t` | **是** | 要删除的 Wiki 页面标题 | +| `--owner` | | 否 | 仓库所有者(自动从 git remote 解析) | +| `--repo` | | 否 | 仓库名称(自动从 git remote 解析) | +| `--format` | | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | | 否 | 开启调试输出 | + +## 返回字段 + +### Table 格式 + +| 列名 | 说明 | +|------|------| +| `message` | 操作结果消息 | + +### JSON 格式 + +```json +{ + "ok": true, + "data": { + "message": "Wiki page deleted successfully" + } +} +``` + +## Workflow + +1. **Confirm** the page title to delete. +2. **Warning** that this operation is **irreversible**. +3. **Optional**: View current content with `wiki +view` for final verification. +4. **Execute** `gitlink-cli wiki +delete --title "<page title>"`. +5. **Report** the deletion result. + +> [!DANGER] +> **删除操作无法撤销!** 建议执行前先备份内容: +> ```bash +> gitlink-cli wiki +view --title "Page" > backup.md +> gitlink-cli wiki +delete --title "Page" +> ``` + +## API + +``` +DELETE https://gateway.gitlink.org.cn/api/wiki/open/deleteWiki +Body: { + "owner": "...", + "repo": "...", + "projectId": 123, + "pageName": "<title>", + "message": "" +} +``` + +**工作流程**: +1. CLI 获取 `project_id` +2. 调用 Gateway API 删除页面 +3. 验证删除是否成功(尝试获取页面) +4. 返回删除结果 + +**删除验证逻辑**: +- 如果删除 API 返回成功 → 删除成功 +- 如果删除 API 失败,尝试获取页面: + - 页面不存在 → 删除成功 + - 页面仍存在 → 删除失败 + +## 使用场景 + +### 场景 1: 删除过时文档 + +```bash +# 查看过时内容 +gitlink-cli wiki +view --title "Old API Reference" + +# 确认后删除 +gitlink-cli wiki +delete --title "Old API Reference" +``` + +### 场景 2: 清理测试页面 + +```bash +# 列出所有页面 +gitlink-cli wiki +list + +# 删除测试页面 +gitlink-cli wiki +delete --title "Test Page 1" +gitlink-cli wiki +delete --title "Test Page 2" +gitlink-cli wiki +delete --title "Test Page 3" +``` + +### 场景 3: 批量删除(谨慎!) + +```bash +#!/bin/bash +# 批量删除包含特定关键词的页面 + +for title in $(gitlink-cli wiki +list --format json | jq -r ".data[].title"); do + # 删除包含 "Draft" 的页面 + if [[ "$title" == *"Draft"* ]]; then + echo "Deleting draft page: $title" + gitlink-cli wiki +delete --title "$title" + fi +done +``` + +### 场景 4: 删除前备份 + +```bash +#!/bin/bash +# 安全删除工作流:先备份再删除 + +title="Page to Delete" + +# 1. 备份内容 +gitlink-cli wiki +view --title "$title" --format json | \ + jq -r ".data.content_decoded" > "${title}-backup.md" + +# 2. 确认删除 +read -p "Backup created at ${title}-backup.md. Delete now? (y/N) " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + gitlink-cli wiki +delete --title "$title" + echo "Page deleted. Backup saved at ${title}-backup.md" +else + echo "Deletion cancelled." +fi +``` + +### 场景 5: 条件删除 + +```bash +#!/bin/bash +# 根据页面内容决定是否删除 + +title="Deprecated Feature" + +# 获取页面内容 +content=$(gitlink-cli wiki +view --title "$title" --format json | \ + jq -r ".data.content_decoded") + +# 检查是否包含"已废弃"标记 +if [[ "$content" == *"此功能已废弃"* ]]; then + echo "Page is deprecated. Deleting..." + gitlink-cli wiki +delete --title "$title" +else + echo "Page is still active. Not deleting." +fi +``` + +## 删除验证 + +### 方法 1: 尝试查看页面 + +```bash +# 删除后验证 +gitlink-cli wiki +delete --title "Test Page" + +# 尝试查看(应该返回 404) +gitlink-cli wiki +view --title "Test Page" +# 预期输出:Error: 404 Not Found +``` + +### 方法 2: 列出所有页面 + +```bash +# 删除前列出 +gitlink-cli wiki +list +# 包含: "Test Page" + +gitlink-cli wiki +delete --title "Test Page" + +# 删除后列出 +gitlink-cli wiki +list +# 不包含: "Test Page" +``` + +### 方法 3: 统计页面数量 + +```bash +# 删除前 +before=$(gitlink-cli wiki +list --format json | jq ".meta.total_count") +echo "Pages before: $before" + +# 删除 +gitlink-cli wiki +delete --title "Old Page" + +# 删除后 +after=$(gitlink-cli wiki +list --format json | jq ".meta.total_count") +echo "Pages after: $after" +echo "Deleted: $((before - after)) page(s)" +``` + +## 常见问题 + +### Q: 删除后能否恢复? + +**A:** **不能**。GitLink Wiki 不提供版本历史或回收站功能。 + +**建议**: +1. 删除前务必备份:`gitlink-cli wiki +view --title "Page" > backup.md` +2. 考虑使用重命名代替删除:`gitlink-cli wiki +update --page "Old" --title "Old-Archived"` +3. 如有备份,可重新创建:`gitlink-cli wiki +create --title "Page" --file backup.md` + +### Q: 删除失败提示 "page not found"? + +**A:** 页面不存在或已被删除。 + +**解决方法**: +```bash +# 查看现有页面 +gitlink-cli wiki +list + +# 确认页面标题正确(区分大小写) +gitlink-cli wiki +delete --title "Correct-Title" +``` + +### Q: 删除后页面链接还能访问吗? + +**A:** 访问已删除页面会返回 **404 Not Found**。 + +如果有外部链接指向该页面,需要: +1. 更新外部链接 +2. 或创建同名新页面 +3. 或设置重定向(GitLink Wiki 不支持,需手动更新) + +### Q: 能否批量删除所有页面? + +**A:** **可以,但极其危险!** + +```bash +#!/bin/bash +# ⚠️ 危险操作:删除所有 Wiki 页面 + +read -p "⚠️ This will delete ALL wiki pages. Continue? (yes/NO) " -r +if [[ "$REPLY" == "yes" ]]; then + for title in $(gitlink-cli wiki +list --format json | jq -r ".data[].title"); do + echo "Deleting: $title" + gitlink-cli wiki +delete --title "$title" + done + echo "All pages deleted." +else + echo "Cancelled." +fi +``` + +### Q: 删除操作需要什么权限? + +**A:** 需要: +- **项目写入权限**(Maintainer 或 Owner 角色) +- **有效的认证 Token** + +如果权限不足: +```bash +# 403 Forbidden → 检查权限 +# 401 Unauthorized → 运行 gitlink-cli auth login +``` + +### Q: 如何防止误删除? + +**A:** 建议: +1. **删除前备份**:总是先备份内容 +2. **使用别名**:创建安全删除别名 +3. **确认操作**:删除前再次确认 +4. **文档规范**:制定删除流程文档 + +## 错误处理 + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `required flag --title is missing` | 未指定页面标题 | 添加 `--title "Page Title"` | +| `page not found` | 页面不存在 | 使用 `wiki +list` 查看可用页面 | +| `401 Unauthorized` | 未登录或 Token 过期 | 运行 `gitlink-cli auth login` | +| `403 Forbidden` | 无权限删除 Wiki | 检查是否有项目写入权限 | +| `failed to delete` | 删除操作失败 | 检查网络连接和 API 可用性 | + +## 安全措施 + +### 1. 删除前备份脚本 + +```bash +#!/bin/bash +# safe-delete.sh - 安全删除 Wiki 页面 + +title="$1" + +if [ -z "$title" ]; then + echo "Usage: ./safe-delete.sh '<Page Title>'" + exit 1 +fi + +# 1. 检查页面是否存在 +if ! gitlink-cli wiki +view --title "$title" >/dev/null 2>&1; then + echo "Error: Page '$title' does not exist." + exit 1 +fi + +# 2. 备份内容 +backup_file="${title}-backup-$(date '+%Y%m%d-%H%M%S').md" +gitlink-cli wiki +view --title "$title" --format json | \ + jq -r ".data.content_decoded" > "$backup_file" + +echo "✓ Backup created: $backup_file" + +# 3. 显示预览 +echo "" +echo "Page content preview:" +head -n 10 "$backup_file" +echo "..." + +# 4. 确认删除 +read -p "Delete '$title' now? (yes/NO) " -r +echo +if [[ "$REPLY" == "yes" ]]; then + gitlink-cli wiki +delete --title "$title" + if [ $? -eq 0 ]; then + echo "✓ Page deleted. Backup saved at: $backup_file" + else + echo "✗ Deletion failed. Backup available at: $backup_file" + fi +else + echo "✗ Deletion cancelled. Backup saved at: $backup_file" +fi +``` + +### 2. 创建删除日志 + +```bash +#!/bin/bash +# deleted-pages.log - 记录所有删除操作 + +log_file="wiki-deletion-log.txt" +title="$1" + +# 记录删除操作 +echo "[$(date '+%Y-%m-%d %H:%M:%S')] Deleted: $title" >> "$log_file" + +# 执行删除 +gitlink-cli wiki +delete --title "$title" + +echo "Deletion logged to: $log_file" +``` + +### 3. 使用 Git 追踪删除 + +如果 Wiki 内容也在 Git 中管理: + +```bash +# 1. Git commit 删除前的状态 +git add docs/ +git commit -m "Backup before wiki deletion: $title" + +# 2. 执行删除 +gitlink-cli wiki +delete --title "$title" + +# 3. 记录删除 +echo "Deleted $title on $(date)" >> wiki-deletions.log +``` + +## 最佳实践 + +### 1. 删除前检查清单 + +在删除 Wiki 页面前,确保: + +- [ ] 已备份页面内容 +- [ ] 确认页面不再需要 +- [ ] 更新了相关链接 +- [ ] 通知了相关团队成员 +- [ ] 有权限执行删除操作 + +### 2. 替代删除的方案 + +**考虑使用重命名代替删除**: + +```bash +# 不删除,而是重命名为"已归档" +gitlink-cli wiki +update --page "Old Feature" --title "Archived-Old-Feature" + +# 或在页面顶部添加废弃标记 +gitlink-cli wiki +update --title "Old Feature" \ + --add "\n\n---\n\n⚠️ **此页面已废弃,请勿使用。**" +``` + +### 3. 批量删除的安全流程 + +```bash +#!/bin/bash +# 安全批量删除工作流 + +# 1. 列出待删除页面 +declare -a pages_to_delete=( + "Test-Page-1" + "Test-Page-2" + "Draft-Document" +) + +# 2. 创建备份目录 +backup_dir="wiki-backup-$(date '+%Y%m%d-%H%M%S')" +mkdir -p "$backup_dir" + +# 3. 备份所有页面 +for title in "${pages_to_delete[@]}"; do + filename=$(echo "$title" | sed 's/[^a-zA-Z0-9_-]/_/g').md + gitlink-cli wiki +view --title "$title" --format json | \ + jq -r ".data.content_decoded" > "$backup_dir/$filename" + echo "Backed up: $title" +done + +# 4. 确认删除 +echo "" +echo "Backup created at: $backup_dir" +read -p "Delete all ${#pages_to_delete[@]} pages now? (yes/NO) " -r +echo + +if [[ "$REPLY" == "yes" ]]; then + # 5. 执行删除 + for title in "${pages_to_delete[@]}"; do + gitlink-cli wiki +delete --title "$title" + echo "Deleted: $title" + done + echo "✓ All pages deleted. Backups saved at: $backup_dir" +else + echo "✗ Cancelled. Backups available at: $backup_dir" +fi +``` + +### 4. 监控删除操作 + +```bash +#!/bin/bash +# 监控 Wiki 页面数量变化 + +# 记录当前页面数量 +current_count=$(gitlink-cli wiki +list --format json | jq ".meta.total_count") +echo "[$(date '+%Y-%m-%d %H:%M:%S')] Current page count: $current_count" >> wiki-monitor.log + +# 如果页面数量异常减少,发出警告 +if [ -f "previous-count.txt" ]; then + previous_count=$(cat previous-count.txt) + if [ "$current_count" -lt "$previous_count" ]; then + echo "⚠️ Warning: Page count decreased from $previous_count to $current_count" + echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: Count decreased: $previous_count -> $current_count" >> wiki-monitor.log + fi +fi + +echo "$current_count" > previous-count.txt +``` + +## 完整示例 + +### 示例:清理过时文档 + +```bash +#!/bin/bash +# 完整的文档清理工作流 + +# 1. 定义过时页面列表 +declare -a outdated_pages=( + "Legacy-API-v1" + "Deprecated-Feature-X" + "Old-Installation-Guide" +) + +# 2. 创建备份 +backup_dir="wiki-cleanup-backup-$(date '+%Y%m%d')" +mkdir -p "$backup_dir" + +echo "=== Wiki Cleanup Process ===" +echo "Backing up outdated pages..." + +for title in "${outdated_pages[@]}"; do + if gitlink-cli wiki +view --title "$title" >/dev/null 2>&1; then + filename=$(echo "$title" | sed 's/[^a-zA-Z0-9_-]/_/g').md + gitlink-cli wiki +view --title "$title" --format json | \ + jq -r ".data.content_decoded" > "$backup_dir/$filename" + echo "✓ Backed up: $title" + else + echo "✗ Skipped (not found): $title" + fi +done + +# 3. 确认删除 +echo "" +echo "Outdated pages to delete:" +printf " - %s\n" "${outdated_pages[@]}" +echo "" +read -p "Proceed with deletion? (yes/NO) " -r +echo + +if [[ "$REPLY" == "yes" ]]; then + echo "Deleting outdated pages..." + + for title in "${outdated_pages[@]}"; do + if gitlink-cli wiki +delete --title "$title" 2>/dev/null; then + echo "✓ Deleted: $title" + else + echo "✗ Failed (already deleted?): $title" + fi + done + + echo "" + echo "✓ Cleanup completed. Backups saved at: $backup_dir" + echo "Remaining pages: $(gitlink-cli wiki +list --format json | jq '.meta.total_count')" +else + echo "✗ Cleanup cancelled. Backups available at: $backup_dir" +fi +``` + +## References + +- [gitlink-wiki](../SKILL.md) +- [wiki +create](wiki-create.md) — 创建 Wiki 页面 +- [wiki +update](wiki-update.md) — 更新 Wiki 页面 +- [wiki +list](wiki-list.md) — 列出 Wiki 页面 +- [gitlink-shared](../../gitlink-shared/SKILL.md) diff --git a/skills/gitlink-wiki/references/wiki-list.md b/skills/gitlink-wiki/references/wiki-list.md new file mode 100644 index 0000000..e3b6ba4 --- /dev/null +++ b/skills/gitlink-wiki/references/wiki-list.md @@ -0,0 +1,136 @@ +# wiki +list + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +列出仓库的所有 Wiki 页面。返回页面标题、URL、更新时间等元信息。 + +## 命令 + +```bash +# 列出当前仓库的所有 Wiki 页面 +gitlink-cli wiki +list + +# 列出指定仓库的 Wiki 页面 +gitlink-cli wiki +list --owner Gitlink --repo forgeplus + +# 使用 JSON 格式输出 +gitlink-cli wiki +list --format json + +# 查看 Wiki 页面总数 +gitlink-cli wiki +list --format json | jq ".data | length" +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--owner` | 否 | 仓库所有者(自动从 git remote 解析) | +| `--repo` | 否 | 仓库名称(自动从 git remote 解析) | +| `--format` | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | 否 | 开启调试输出 | + +## 返回字段 + +### Table 格式 + +| 列名 | 说明 | +|------|------| +| `title` | Wiki 页面标题 | +| `sub_url` | 页面访问路径(URL 编码) | +| `updated_at` | 最后更新时间 | + +### JSON 格式 + +```json +{ + "ok": true, + "data": [ + { + "title": "Home", + "sub_url": "https://www.gitlink.org.cn/Gitlink/forgeplus/wiki/Home", + "updated_at": "2026-06-01T10:30:00Z" + }, + { + "title": "API-Reference", + "sub_url": "https://www.gitlink.org.cn/Gitlink/forgeplus/wiki/API-Reference", + "updated_at": "2026-06-01T11:15:00Z" + } + ], + "meta": { + "total_count": 2 + } +} +``` + +## Workflow + +1. **Check** if `--owner` and `--repo` are provided or can be auto-resolved. +2. **Execute** `gitlink-cli wiki +list`. +3. **Display** the list of Wiki pages with titles and URLs. + +## API + +``` +GET https://gateway.gitlink.org.cn/api/wiki/open/wikiPages +Query: owner={owner}&repo={repo}&projectId={project_id} +``` + +**注意**: +- CLI 自动获取 `project_id` +- 响应会被清理:移除 `wiki_clone_link` 字段 +- `sub_url` 会被 URL 解码以便阅读 + +## 使用场景 + +### 场景 1: 发现项目文档 + +当用户询问"这个项目有什么文档"时: + +```bash +gitlink-cli wiki +list +``` + +### 场景 2: 检查 Wiki 是否启用 + +当返回空列表时,说明项目未启用 Wiki 或没有创建任何页面。 + +### 场景 3: 批量处理所有 Wiki 页面 + +```bash +# 获取所有 Wiki 页面标题 +titles=$(gitlink-cli wiki +list --format json | jq -r ".data[].title") + +# 遍历每个页面 +for title in $titles; do + echo "Processing: $title" + gitlink-cli wiki +view --title "$title" +done +``` + +## 常见问题 + +### Q: 返回空列表? + +**A:** 可能原因: +1. 项目没有创建任何 Wiki 页面 +2. 项目未启用 Wiki 功能 +3. `owner/repo` 指定错误 + +### Q: `sub_url` 字段是什么? + +**A:** Wiki 页面的完整访问 URL,格式为: +``` +https://www.gitlink.org.cn/{owner}/{repo}/wiki/{page_title} +``` + +### Q: 如何获取页面总数? + +**A:** 使用 JSON 格式并查看 `meta.total_count`: +```bash +gitlink-cli wiki +list --format json | jq ".meta.total_count" +``` + +## References + +- [gitlink-wiki](../SKILL.md) +- [gitlink-shared](../../gitlink-shared/SKILL.md) diff --git a/skills/gitlink-wiki/references/wiki-update.md b/skills/gitlink-wiki/references/wiki-update.md new file mode 100644 index 0000000..f0f8aa1 --- /dev/null +++ b/skills/gitlink-wiki/references/wiki-update.md @@ -0,0 +1,492 @@ +# wiki +update + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **⚠️ 写入操作** — 执行前必须确认用户意图。 + +更新现有 Wiki 页面。支持三种模式:**覆盖**、**追加**、**重命名**。 + +## 命令 + +### 覆盖模式(完全替换内容) + +```bash +# 覆盖整个页面内容 +gitlink-cli wiki +update --title "Home" --cover "# New Content\n\nThis replaces everything." + +# 从文件覆盖 +gitlink-cli wiki +update --title "API Reference" --file new-api.md +``` + +### 追加模式(在现有内容后追加) + +```bash +# 追加内容到现有页面 +gitlink-cli wiki +update --title "Home" --add "\n\n## New Section\n\nAdditional content." + +# 从文件追加 +gitlink-cli wiki +update --title "Guide" --add "" --file appendix.md +``` + +### 重命名模式(更改页面标题) + +```bash +# 重命名页面(保留原内容) +gitlink-cli wiki +update --page "Old-Title" --title "New-Title" + +# 重命名并更新内容 +gitlink-cli wiki +update --page "Old-Title" --title "New-Title" --cover "Updated content" +``` + +## 参数 + +| 参数 | Short | 必填 | 说明 | +|------|-------|------|------| +| `--title` | `-t` | **是** | 目标页面标题(更新后的标题,用于重命名) | +| `--page` | `-p` | 否 | 当前页面标题(用于查找和重命名,默认同 `--title`) | +| `--cover` | `-c` | 否* | 覆盖整个页面内容(纯文本) | +| `--add` | `-a` | 否* | 追加内容到现有页面(纯文本) | +| `--file` | `-f` | 否 | 从文件读取内容(配合 `--cover` 或 `--add` 使用) | +| `--message` | `-m` | 否 | 提交消息(可选) | +| `--owner` | | 否 | 仓库所有者(自动从 git remote 解析) | +| `--repo` | | 否 | 仓库名称(自动从 git remote 解析) | +| `--format` | | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | | 否 | 开启调试输出 | + +* `--cover` 或 `--add` 必须指定其中一个,或都不指定(仅重命名) + +## 返回字段 + +### Table 格式 + +| 列名 | 说明 | +|------|------| +| `title` | 更新后的页面标题 | +| `message` | 操作结果消息 | + +### JSON 格式 + +```json +{ + "ok": true, + "data": { + "title": "Updated Title", + "message": "Wiki page updated successfully" + } +} +``` + +## 三种更新模式 + +### 1. 覆盖模式 (`--cover`) + +**完全替换页面内容**: + +```bash +gitlink-cli wiki +update --title "Home" --cover "# New Home Page + +This completely replaces the old content." +``` + +**工作流程**: +1. 用户提供新内容 +2. CLI 直接用新内容替换整个页面 +3. 旧内容**完全丢失** + +**使用场景**: +- 完全重写页面 +- 修正错误内容 +- 大规模内容更新 + +### 2. 追加模式 (`--add`) + +**在现有内容基础上追加**: + +```bash +gitlink-cli wiki +update --title "Home" --add "\n\n## Changelog + +### v1.0.0 (2026-06-01) +- Initial release" +``` + +**工作流程**: +1. CLI 获取当前页面内容 +2. 将新内容追加到现有内容后 +3. 提交更新后的完整内容 + +**使用场景**: +- 添加新章节 +- 追加更新日志 +- 补充补充说明 + +### 3. 重命名模式 (`--page` + `--title`) + +**更改页面标题**: + +```bash +# 仅重命名(保留原内容) +gitlink-cli wiki +update --page "Old-Title" --title "New-Title" + +# 重命名并更新内容 +gitlink-cli wiki +update --page "Old-Title" --title "New-Title" --cover "Updated" +``` + +**工作流程**: +1. `--page` 指定当前页面标题(用于查找) +2. `--title` 指定新标题 +3. 如果指定 `--cover` 或 `--add`,同时更新内容 + +**使用场景**: +- 修正页面标题拼写 +- 调整命名规范 +- 页面重组 + +## Workflow + +### 覆盖模式 + +1. **Confirm** the new content with the user. +2. **Warning** that this will replace all existing content. +3. **Execute** `gitlink-cli wiki +update --title "<title>" --cover "<new content>"`. +4. **Report** the update result. + +### 追加模式 + +1. **Confirm** the content to append. +2. **Execute** `gitlink-cli wiki +update --title "<title>" --add "<content>"`. +3. **Report** the update result. + +### 重命名模式 + +1. **Confirm** the old title (`--page`) and new title (`--title`). +2. **Execute** `gitlink-cli wiki +update --page "<old>" --title "<new>"`. +3. **Report** the rename result. + +> [!CAUTION] +> **覆盖模式** 会完全替换页面内容,无法撤销!建议先使用 `wiki +view` 查看当前内容,必要时手动备份。 + +## API + +``` +PUT https://gateway.gitlink.org.cn/api/wiki/open/updateWiki +Body: { + "owner": "...", + "repo": "...", + "projectId": 123, + "pageName": "<current-title>", + "title": "<new-title>", + "content_base64": "<base64-encoded-content>", + "message": "<optional-message>" +} +``` + +**工作流程**: +1. CLI 获取 `project_id` +2. 如果是追加模式,先获取当前页面内容 +3. 将内容 Base64 编码 +4. 调用 Gateway API 更新页面 +5. 返回更新结果 + +## 使用场景 + +### 场景 1: 修正文档错误 + +```bash +# 查看当前内容 +gitlink-cli wiki +view --title "API Reference" + +# 修正错误 +gitlink-cli wiki +update --title "API Reference" \ + --file corrected-api.md +``` + +### 场景 2: 添加更新日志 + +```bash +# 追加更新日志到首页 +gitlink-cli wiki +update --title "Home" --add ' +## Changelog + +### v2.0.0 (2026-06-01) +- Added new feature X +- Fixed bug Y +- Improved performance Z' +``` + +### 场景 3: 重命名页面 + +```bash +# 将 "api" 重命名为 "API Reference" +gitlink-cli wiki +update --page "api" --title "API Reference" + +# 重命名并更新内容 +gitlink-cli wiki +update --page "old-guide" --title "User-Guide" \ + --cover "# User Guide\n\nUpdated content" +``` + +### 场景 4: 批量更新多个页面 + +```bash +#!/bin/bash +# 批量更新所有页面的页脚 + +declare -A pages=( + ["Home"]="home.md" + ["API-Reference"]="api.md" + ["Guide"]="guide.md" +) + +for title in "${!pages[@]}"; do + file="${pages[$title]}" + + # 读取文件内容作为覆盖内容 + echo "Updating: $title from $file" + gitlink-cli wiki +update --title "$title" --file "$file" +done +``` + +### 场景 5: 增量更新文档 + +```bash +#!/bin/bash +# 为所有页面添加"最后更新"时间戳 + +for title in $(gitlink-cli wiki +list --format json | jq -r ".data[].title"); do + current_date=$(date "+%Y-%m-%d") + + gitlink-cli wiki +update --title "$title" \ + --add "\n\n---\n\n*Last updated: $current_date*" +done +``` + +## 模式选择指南 + +### 何时使用覆盖模式? + +✅ **使用覆盖模式**: +- 完全重写页面内容 +- 修正严重错误 +- 大规模内容更新 +- 从文件导入新版本 + +❌ **避免使用覆盖模式**: +- 只需添加小段内容 +- 需要保留部分现有内容 +- 不确定要修改的具体内容 + +### 何时使用追加模式? + +✅ **使用追加模式**: +- 添加新章节 +- 追加更新日志 +- 补充补充说明 +- 保持历史内容 + +❌ **避免使用追加模式**: +- 需要修正现有内容 +- 页面内容过长 +- 需要结构性修改 + +### 何时使用重命名模式? + +✅ **使用重命名模式**: +- 修正拼写错误 +- 统一命名规范 +- 页面重组 +- 调整文档结构 + +## 常见问题 + +### Q: 覆盖模式能否撤销? + +**A:** **不能**。覆盖模式会完全替换内容,无法自动撤销。 + +**建议**: +1. 先使用 `wiki +view` 查看当前内容 +2. 必要时手动备份:`gitlink-cli wiki +view --title "Page" > backup.md` +3. 再执行覆盖更新 + +### Q: 追加模式的内容位置? + +**A:** 追加的内容会添加到现有内容的**末尾**。 + +如果需要精确控制位置: +1. 先查看当前内容 +2. 手动编辑(合并旧内容 + 新内容) +3. 使用覆盖模式更新 + +### Q: 重命名后旧标题还能访问吗? + +**A:** **不能**。重命名后: +- 旧标题页面不存在 +- 使用旧标题访问会返回 404 +- 需要更新所有指向旧页面的链接 + +### Q: 如何同时修改标题和内容? + +**A:** 使用 `--page` + `--title` + `--cover`: +```bash +gitlink-cli wiki +update \ + --page "Old-Title" \ + --title "New-Title" \ + --cover "New content" +``` + +### Q: 更新失败提示 "page not found"? + +**A:** 可能原因: +1. `--title` 指定的页面不存在 +2. 如果使用 `--page`,当前页面不存在 +3. `owner/repo` 指定错误 + +**解决方法**: +```bash +# 先列出所有页面 +gitlink-cli wiki +list + +# 确认页面标题正确(区分大小写) +gitlink-cli wiki +update --title "Correct-Title" --cover "..." +``` + +### Q: 追加模式获取旧内容失败? + +**A:** 可能原因: +1. 页面不存在 +2. 网络问题 +3. 权限不足 + +**解决方法**: +```bash +# 检查页面是否存在 +gitlink-cli wiki +view --title "Page-Name" + +# 如果页面不存在,先创建 +gitlink-cli wiki +create --title "Page-Name" --content "..." +``` + +## 错误处理 + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `required flag --title is missing` | 未指定目标标题 | 添加 `--title "Page Title"` | +| `--cover or --file is required` | 未提供更新内容 | 添加 `--cover "..."` 或 `--file file.md` | +| `failed to fetch current page content` | 追加模式下页面不存在 | 先创建页面或检查标题 | +| `page not found` | 指定页面不存在 | 使用 `wiki +list` 查看可用页面 | +| `401 Unauthorized` | 未登录或 Token 过期 | 运行 `gitlink-cli auth login` | +| `403 Forbidden` | 无权限更新 Wiki | 检查是否有项目写入权限 | + +## 最佳实践 + +### 1. 更新前备份 + +```bash +# 更新前先备份当前内容 +gitlink-cli wiki +view --title "Important Page" --format json | \ + jq -r ".data.content_decoded" > backup.md + +# 然后执行更新 +gitlink-cli wiki +update --title "Important Page" --file new-content.md +``` + +### 2. 验证更新结果 + +```bash +# 更新后查看新内容 +gitlink-cli wiki +view --title "Page" --format json | \ + jq -r ".data.content_decoded" +``` + +### 3. 使用文件进行复杂更新 + +```bash +# 1. 导出当前内容 +gitlink-cli wiki +view --title "Page" --format json | \ + jq -r ".data.content_decoded" > temp.md + +# 2. 手动编辑 temp.md + +# 3. 更新回 Wiki +gitlink-cli wiki +update --title "Page" --file temp.md + +# 4. 清理 +rm temp.md +``` + +### 4. 批量重命名规范 + +```bash +#!/bin/bash +# 统一命名规范:将空格替换为连字符 + +for title in $(gitlink-cli wiki +list --format json | jq -r ".data[].title"); do + # 如果标题包含空格 + if [[ "$title" =~ " " ]]; then + # 生成新标题(空格替换为连字符) + new_title=$(echo "$title" | sed 's/ /-/g') + + echo "Renaming: '$title' -> '$new_title'" + gitlink-cli wiki +update --page "$title" --title "$new_title" + fi +done +``` + +### 5. 增量更新工作流 + +```bash +#!/bin/bash +# 安全的追加模式工作流 + +title="Home" +new_content="## New Section\n\nNew content here." + +# 1. 先检查页面是否存在 +if gitlink-cli wiki +view --title "$title" >/dev/null 2>&1; then + # 2. 追加内容 + gitlink-cli wiki +update --title "$title" --add "\n\n$new_content" + echo "Content appended to $title" +else + # 3. 页面不存在,创建新页面 + gitlink-cli wiki +create --title "$title" --content "$new_content" + echo "New page $title created" +fi +``` + +## 完整示例 + +### 示例:重构项目文档 + +```bash +#!/bin/bash +# 文档重构工作流 + +# 1. 备份所有页面 +mkdir -p wiki-backup +for title in $(gitlink-cli wiki +list --format json | jq -r ".data[].title"); do + filename=$(echo "$title" | sed 's/[^a-zA-Z0-9_-]/_/g').md + gitlink-cli wiki +view --title "$title" --format json | \ + jq -r ".data.content_decoded" > "wiki-backup/$filename" + echo "Backed up: $title -> $filename" +done + +# 2. 重命名页面(统一命名规范) +gitlink-cli wiki +update --page "api" --title "API-Reference" +gitlink-cli wiki +update --page "user guide" --title "User-Guide" + +# 3. 更新首页内容 +gitlink-cli wiki +update --title "Home" --file new-home.md + +# 4. 为所有页面添加页脚 +for title in $(gitlink-cli wiki +list --format json | jq -r ".data[].title"); do + gitlink-cli wiki +update --title "$title" \ + --add "\n\n---\n\n*Updated: $(date '+%Y-%m-%d')*" +done + +echo "Wiki restructuring completed!" +``` + +## References + +- [gitlink-wiki](../SKILL.md) +- [wiki +create](wiki-create.md) — 创建 Wiki 页面 +- [wiki +view](wiki-view.md) — 查看 Wiki 页面 +- [wiki +delete](wiki-delete.md) — 删除 Wiki 页面 +- [gitlink-shared](../../gitlink-shared/SKILL.md) diff --git a/skills/gitlink-wiki/references/wiki-view.md b/skills/gitlink-wiki/references/wiki-view.md new file mode 100644 index 0000000..073b29e --- /dev/null +++ b/skills/gitlink-wiki/references/wiki-view.md @@ -0,0 +1,213 @@ +# wiki +view + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 + +查看指定 Wiki 页面的完整内容,包括 Markdown 源文本。 + +## 命令 + +```bash +# 查看 Wiki 页面内容 +gitlink-cli wiki +view --title "Home" + +# 查看指定仓库的 Wiki 页面 +gitlink-cli wiki +view --owner Gitlink --repo forgeplus --title "API-Reference" + +# 使用 JSON 格式查看(包含 base64 和 decoded 内容) +gitlink-cli wiki +view --title "Home" --format json + +# 将 Wiki 内容保存到文件 +gitlink-cli wiki +view --title "Home" --format json | jq -r ".data.content_decoded" > home.md +``` + +## 参数 + +| 参数 | Short | 必填 | 说明 | +|------|-------|------|------| +| `--title` | `-t` | **是** | Wiki 页面标题(区分大小写) | +| `--owner` | | 否 | 仓库所有者(自动从 git remote 解析) | +| `--repo` | | 否 | 仓库名称(自动从 git remote 解析) | +| `--format` | | 否 | 输出格式: `json`/`table`/`yaml` | +| `--debug` | | 否 | 开启调试输出 | + +## 返回字段 + +### Table 格式 + +| 列名 | 说明 | +|------|------| +| `title` | Wiki 页面标题 | +| `content` | 页面内容(自动解码后的文本) | +| `updated_at` | 最后更新时间 | + +### JSON 格式 + +```json +{ + "ok": true, + "data": { + "title": "Home", + "content_base64": "I0hvbWUKCisqKldlbGNvbWUgdG8gdGhlIHByb2plY3QgIWJqKio=", + "content_decoded": "# Home\n\n**Welcome to the project!**\n\n## Getting Started\n...", + "updated_at": "2026-06-01T10:30:00Z" + } +} +``` + +**字段说明**: +- `content_base64` - 原始 Base64 编码内容(API 返回) +- `content_decoded` - 自动解码后的文本内容(CLI 提供) + +## Workflow + +1. **Confirm** the page title with the user. +2. **Execute** `gitlink-cli wiki +view --title "<page title>"`. +3. **Display** the page content (auto-decoded). +4. **Optional**: Save content to file if requested. + +## API + +``` +GET https://gateway.gitlink.org.cn/api/wiki/open/getWiki +Query: owner={owner}&repo={repo}&projectId={project_id}&pageName={title} +``` + +**工作流程**: +1. CLI 获取 `project_id` +2. 调用 Gateway API 获取页面 +3. 解码 `content_base64` 为 `content_decoded` +4. 返回解码后的内容 + +## 使用场景 + +### 场景 1: 查看单个页面 + +当用户询问"查看 API 文档页面"时: + +```bash +gitlink-cli wiki +view --title "API Reference" +``` + +### 场景 2: 导出 Wiki 页面 + +```bash +# 导出为 Markdown 文件 +gitlink-cli wiki +view --title "Home" --format json | \ + jq -r ".data.content_decoded" > home.md +``` + +### 场景 3: 批量导出所有 Wiki 页面 + +```bash +#!/bin/bash +# 导出所有 Wiki 页面为 Markdown 文件 + +titles=$(gitlink-cli wiki +list --format json | jq -r ".data[].title") + +for title in $titles; do + # 清理文件名(替换空格和特殊字符) + filename=$(echo "$title" | sed 's/[^a-zA-Z0-9_-]/_/g').md + + echo "Exporting: $title -> $filename" + gitlink-cli wiki +view --title "$title" --format json | \ + jq -r ".data.content_decoded" > "$filename" +done +``` + +### 场景 4: 检查页面是否存在 + +```bash +# 检查页面是否存在(退出码 0=存在,非0=不存在) +if gitlink-cli wiki +view --title "Some Page" >/dev/null 2>&1; then + echo "Page exists" +else + echo "Page does not exist" +fi +``` + +## 常见问题 + +### Q: 提示 "page not found"? + +**A:** 可能原因: +1. 页面标题不匹配(区分大小写) +2. 页面不存在 +3. `owner/repo` 指定错误 + +**解决方法**: +```bash +# 先列出所有页面确认标题 +gitlink-cli wiki +list +``` + +### Q: 内容显示为乱码? + +**A:** 确保: +1. 内容是有效的 UTF-8 编码 +2. 使用 `--format json` 查看 `content_decoded` 字段 +3. 终端支持 UTF-8 显示 + +### Q: 如何获取原始 Base64 内容? + +**A:** 使用 JSON 格式查看 `content_base64` 字段: +```bash +gitlink-cli wiki +view --title "Home" --format json | jq ".data.content_base64" +``` + +### Q: 支持哪些 Markdown 语法? + +**A:** GitLink Wiki 支持 CommonMark 标准,包括: +- 标题、列表、代码块 +- 链接、图片、表格 +- 粗体、斜体、引用 + +## 错误处理 + +| 错误 | 原因 | 解决方案 | +|------|------|----------| +| `required flag --title is missing` | 未指定页面标题 | 添加 `--title "Page Title"` | +| `failed to fetch project_id` | 项目不存在或无权限 | 检查 `--owner` 和 `--repo` | +| `failed to decode content` | Base64 解码失败 | 检查内容是否为有效 Base64 | +| `404 Not Found` | 页面不存在 | 使用 `wiki +list` 查看可用页面 | + +## 最佳实践 + +### 1. 页面标题规范 + +使用一致的命名规范: +```bash +# 推荐:使用连字符 +"Getting-Started" +"API-Reference" + +# 避免:空格和特殊字符 +"Getting Started" # 需要引号 +"API/Reference" # 斜杠可能被误解为路径 +``` + +### 2. 内容验证 + +查看页面后验证内容完整性: +```bash +gitlink-cli wiki +view --title "Home" --format json | \ + jq -r ".data.content_decoded" | wc -l +``` + +### 3. 批量操作 + +结合其他命令批量处理 Wiki: +```bash +# 查看所有页面的行数 +for title in $(gitlink-cli wiki +list --format json | jq -r ".data[].title"); do + lines=$(gitlink-cli wiki +view --title "$title" --format json | \ + jq -r ".data.content_decoded" | wc -l) + echo "$title: $lines lines" +done +``` + +## References + +- [gitlink-wiki](../SKILL.md) +- [wiki +list](wiki-list.md) — 列出 Wiki 页面 +- [wiki +create](wiki-create.md) — 创建 Wiki 页面 +- [gitlink-shared](../../gitlink-shared/SKILL.md) diff --git a/skills/gitlink-workflow/examples/full-automation-workflow.md b/skills/gitlink-workflow/examples/full-automation-workflow.md new file mode 100644 index 0000000..ff1cc98 --- /dev/null +++ b/skills/gitlink-workflow/examples/full-automation-workflow.md @@ -0,0 +1,579 @@ +# AI Agent 自动化工作流完整示例 + +本文档展示如何组合使用多个 gitlink-cli 工作流,实现完整的 AI Agent 自动化项目管理。 + +## 🤖 AI Agent 完整工作流 + +### 场景:新项目从创建到发布的完整自动化 + +这个示例展示 AI Agent 如何自动化管理一个软件项目的完整生命周期,从仓库创建到版本发布。 + +## 工作流组合 + +### 1. 项目初始化阶段 + +```python +# AI Agent 项目初始化 +def initialize_new_project(project_name, description): + """完整的项目初始化工作流""" + + # 1. 创建仓库 + repo = create_repository(project_name, description) + + # 2. 初始化项目结构 + setup_project_structure(repo) + + # 3. 配置 CI/CD + configure_ci_cd(repo) + + # 4. 创建初始 Issue + create_initial_issues(repo) + + return repo + +# 执行 +project = initialize_new_project( + "my-awesome-project", + "一个很棒的项目,用于演示自动化工作流" +) +``` + +### 2. 开发阶段自动化 + +```python +# AI Agent 开发管理 +def manage_development_workflow(repo): + """开发阶段的自动化管理""" + + while development_in_progress: + # 1. 自动分类新 Issue + triage_new_issues(repo) + + # 2. 审查新的 PR + review_pull_requests(repo) + + # 3. 更新项目进度 + update_project_status(repo) + + # 4. 检查是否需要发布 + if should_release(repo): + generate_release_notes(repo) + create_release(repo) + + sleep(cycle_interval) +``` + +### 3. Sprint 自动化 + +```python +# AI Agent Sprint 管理 +def automate_sprint_management(repo): + """完整的 Sprint 自动化管理""" + + # Sprint 开始 + sprint_number = start_new_sprint(repo) + + # Sprint 监控 + monitor_sprint_progress(repo, sprint_number) + + # Sprint 结束 + end_sprint(repo, sprint_number) + generate_sprint_report(repo, sprint_number) + +# 执行 Sprint 工作流 +sprint_result = automate_sprint_management(project) +``` + +## 完整的端到端示例 + +### 示例:自动化 Issue 到 Release 流程 + +```bash +#!/bin/bash + +# 完整的自动化工作流脚本 + +OWNER="ai-agent" +REPO="demo-project" +PROJECT_NAME="AI Agent Demo" + +echo "🤖 启动 AI Agent 自动化工作流..." + +# 阶段 1: 项目创建 +echo "📦 阶段 1: 创建项目" +gitlink-cli repo +create \ + --name "$REPO" \ + --description "$PROJECT_NAME" \ + --private false + +# 初始化本地仓库 +cd "$REPO" +git init +git remote add gitlink "https://www.gitlink.org.cn/$OWNER/$REPO.git" + +# 创建基础文件 +echo "# $PROJECT_NAME" > README.md +echo "MIT License" > LICENSE +git add . +git commit -m "Initial commit" +git push -u gitlink master:master + +# 设置分支保护 +gitlink-cli branch +protect --owner "$OWNER" --repo "$REPO" --name master + +# 阶段 2: 创建开发 Issue +echo "🎯 阶段 2: 创建开发 Issue" +FEATURES=( + "用户认证系统" + "数据管理模块" + "API 接口开发" + "前端界面设计" + "测试框架搭建" +) + +for feature in "${FEATURES[@]}"; do + gitlink-cli issue +create \ + --owner "$OWNER" \ + --repo "$REPO" \ + --title "开发 $feature" \ + --body "## 任务描述 + +实现 $feature 功能 + +## 技术要求 +- 代码规范 +- 单元测试 +- 文档完整 + +## 验收标准 +- 功能正常工作 +- 测试通过 +- 代码审查通过" +done + +# 阶段 3: 模拟开发和 PR 创建 +echo "🔧 阶段 3: 模拟开发工作" + +# 创建功能分支 +for feature in "${FEATURES[@]}"; do + # 模拟分支名(将中文转为拼音) + branch_name="feature-$(echo $feature | md5sum | cut -c1-8)" + + git checkout -b "$branch_name" + + # 模拟开发工作 + echo "// $feature 实现" > "${feature}.js" + git add . + git commit -m "Implement $feature" + git push gitlink "$branch_name" + + # 创建 PR + gitlink-cli pr +create \ + --owner "$OWNER" \ + --repo "$REPO" \ + --title "Feature: $feature" \ + --head "$branch_name" \ + --base master \ + --body "## 功能说明 + +实现 $feature 功能 + +## 变更内容 +- 添加核心功能 +- 实现相关测试 +- 更新文档 + +## 测试情况 +- 单元测试通过 +- 集成测试通过 +- 手工测试完成" + + git checkout master +done + +# 阶段 4: 自动 Issue 分类 +echo "🏷️ 阶段 4: 自动分类 Issue" + +# 获取所有开放 Issue +ISSUES=$(gitlink-cli issue +list --owner "$OWNER" --repo "$REPO" --state open --format json) + +# 为 Issue 添加标签 +echo "$ISSUES" | jq -r '.data.issues[].id' | while read issue_id; do + echo "处理 Issue #$issue_id" + + # 获取 Issue 详情 + ISSUE_DETAIL=$(gitlink-cli issue +view --owner "$OWNER" --repo "$REPO" --id "$issue_id" --format json) + TITLE=$(echo "$ISSUE_DETAIL" | jq -r '.data.subject') + + # 基于标题分类 + if echo "$TITLE" | grep -iq "认证"; then + echo " → 分类为: feature + security" + # 实际执行时取消注释 + # gitlink-cli api POST "/$OWNER/$REPO/issues/$issue_id" --body '{"issue_tag_ids":[1,5]}' + else + echo " → 分类为: feature" + # gitlink-cli api POST "/$OWNER/$REPO/issues/$issue_id" --body '{"issue_tag_ids":[1]}' + fi +done + +# 阶段 5: PR 审查 +echo "🔍 阶段 5: 自动 PR 审查" + +# 获取开放 PR +PRS=$(gitlink-cli pr +list --owner "$OWNER" --repo "$REPO" --state open --format json) + +echo "$PRS" | jq -r '.data.prs[].id' | while read pr_id; do + echo "审查 PR #$pr_id" + + # 获取 PR 详情 + PR_DETAIL=$(gitlink-cli pr +view --owner "$OWNER" --repo "$REPO" --id "$pr_id" --format json) + PR_AUTHOR=$(echo "$PR_DETAIL" | jq -r '.data.author.login') + PR_TITLE=$(echo "$PR_DETAIL" | jq -r '.data.title') + + # 简单的代码检查(这里只是模拟) + REVIEW_COMMENTS="# 🔍 自动审查结果 + +## PR 信息 +- **标题**: $PR_TITLE +- **作者**: $PR_AUTHOR +- **状态**: 待审查 + +## ✅ 自动检查 +- 代码提交正常 +- 变更描述清晰 +- 符合项目规范 + +## 💡 建议 +- 添加单元测试 +- 更新相关文档 +- 确认向后兼容性 + +## 📋 审查结论 +代码质量良好,建议合并。" + + echo " → 添加审查评论" + # 实际执行时取消注释 + # gitlink-cli api POST "/$OWNER/$REPO/pulls/$pr_id/reviews" --body "{\"body\":\"$REVIEW_COMMENTS\",\"event\":\"APPROVE\"}" +done + +# 阶段 6: 生成 Release Notes +echo "📝 阶段 6: 生成 Release Notes" + +# 合并所有 PR(模拟) +echo "合并所有功能 PR..." +MERGED_PRS=$(gitlink-cli pr +list --owner "$OWNER" --repo "$REPO" --state merged --format json) + +# 生成 Release Notes +RELEASE_NOTES="# 🎉 v1.0.0 首个版本发布 + +## 📊 版本概述 +这是 $PROJECT_NAME 的首个稳定版本,包含了核心功能的完整实现。 + +## ✨ 新功能 +- 用户认证系统:完整的登录注册功能 +- 数据管理模块:高效的数据存储和检索 +- API 接口:RESTful API 设计 +- 前端界面:现代化的用户界面 +- 测试框架:完整的自动化测试 + +## 🐛 Bug 修复 +- 修复认证过程中的边界问题 +- 解决数据一致性问题 +- 优化 API 响应性能 + +## 🔧 技术改进 +- 代码结构优化 +- 性能提升 30% +- 安全性增强 + +## 📚 文档更新 +- 用户手册完善 +- API 文档更新 +- 开发指南补充 + +## 🙏 贡献者 +感谢所有参与开发的贡献者! + +## 📥 安装方法 +\`\`\`bash +# 使用 npm 安装 +npm install $OWNER/$REPO@v1.0.0 + +# 或使用 yarn +yarn add $OWNER/$REPO@v1.0.0 +\`\`\` + +## 🔄 升级指南 +从之前的版本升级,请参考迁移指南。 + +## 📚 完整文档 +- 用户指南: https://www.gitlink.org.cn/$OWNER/$REPO/wiki +- API 文档: https://www.gitlink.org.cn/$OWNER/$REPO/api-docs + +--- +**发布日期**: $(date +%Y-%m-%d) +**下一版本**: v1.1.0 (计划于 $(date -d "1 month" +%Y-%m-%d) 发布)" + +# 创建 Release +echo "创建 Release v1.0.0..." +gitlink-cli release +create \ + --owner "$OWNER" \ + --repo "$REPO" \ + --tag "v1.0.0" \ + --name "v1.0.0" \ + --body "$RELEASE_NOTES" + +# 阶段 7: Sprint 报告 +echo "📊 阶段 7: 生成 Sprint 报告" + +SPRINT_START=$(date -d "14 days ago" +%Y-%m-%d) +SPRINT_END=$(date +%Y-%m-%d) + +SPRINT_REPORT="# 📊 Sprint 1 完成报告 + +## 📅 时间信息 +- **Sprint 周期**: $SPRINT_START 至 $SPRINT_END +- **团队规模**: AI Agent x 1 +- **工作模式**: 自动化开发 + +## 🎯 目标达成 +### 计划完成度 +- **计划 Issue**: 5 个 +- **实际完成**: 5 个 +- **完成率**: 100% + +### 质量指标 +- **代码质量**: 优秀 +- **测试覆盖率**: 95% +- **文档完整度**: 100% + +## 💻 工作统计 +### 代码提交 +- **总提交数**: 42 次 +- **日均提交**: 3 次/天 +- **代码行数**: +2,450 -180 行 + +### Issue 处理 +- **关闭 Issue**: 5 个 +- **新建 Issue**: 0 个 +- **平均处理时间**: 2.5 天 + +### PR 合并 +- **合并 PR**: 5 个 +- **平均审查时间**: 1 小时 +- **平均合并时间**: 2 小时 + +## 🎉 主要成就 +1. ✅ 完成用户认证系统开发 +2. ✅ 实现数据管理模块 +3. ✅ 构建 RESTful API +4. ✅ 设计现代化前端界面 +5. ✅ 建立完整测试体系 + +## 📈 性能指标 +- **开发效率**: 高 +- **代码质量**: 优秀 +- **自动化程度**: 95% +- **文档完整度**: 100% + +## 🔮 下期规划 +- 性能优化和改进 +- 新功能模块开发 +- 国际化支持 +- 移动端适配 + +--- +**AI Agent 自动化工作流演示** +**报告生成**: $(date +%Y-%m-%d %H:%M:%S)" + +# 保存 Sprint 报告 +REPORT_FILE="sprint_reports/sprint_1_$(date +%Y%m%d).md" +mkdir -p sprint_reports +echo "$SPRINT_REPORT" > "$REPORT_FILE" + +echo "🎉 AI Agent 自动化工作流完成!" +echo "" +echo "📊 项目统计:" +echo " 仓库: https://www.gitlink.org.cn/$OWNER/$REPO" +echo " Issue: 5 个全部完成" +echo " PR: 5 个全部合并" +echo " Release: v1.0.0 已发布" +echo "" +echo "📄 生成的文档:" +echo " - Release Notes: https://www.gitlink.org.cn/$OWNER/$REPO/releases/v1.0.0" +echo " - Sprint 报告: $REPORT_FILE" +``` + +## Claude Code 集成示例 + +### 在 Claude Code 中使用工作流 + +```markdown +# 用户指令 + +帮助我创建一个新的项目并完成首个版本的发布。 + +# Claude Code 执行 + +我会使用 gitlink-cli 的自动化工作流来完成这个任务: + +1. **创建仓库** - 使用 workflow-repo-setup +2. **管理 Issue** - 使用 workflow-issue-triage +3. **审查 PR** - 使用 workflow-pr-review +4. **生成 Release** - 使用 workflow-release-notes +5. **总结报告** - 使用 workflow-sprint-report + +让我开始执行... +``` + +### 技能组合使用 + +```python +# AI Agent 多技能组合 +class GitLinkAgent: + def __init__(self, owner, repo): + self.owner = owner + self.repo = repo + self.cli = "gitlink-cli" + + def complete_project_workflow(self): + """完整的项目工作流""" + + # 阶段 1: 初始化 + self.setup_repository() + + # 阶段 2: 开发管理 + self.manage_development() + + # 阶段 3: 质量控制 + self.automated_review() + + # 阶段 4: 发布管理 + self.create_release() + + # 阶段 5: 报告总结 + self.generate_reports() + + def setup_repository(self): + """仓库初始化""" + # 使用 workflow-repo-setup + create_repo_cmd = f"{self.cli} repo +create --name {self.repo}" + subprocess.run(create_repo_cmd.split()) + + protect_branch_cmd = f"{self.cli} branch +protect --name master" + subprocess.run(protect_branch_cmd.split()) + + def manage_development(self): + """开发管理""" + # 监控新 Issue 并自动分类 + issues = self.get_new_issues() + for issue in issues: + self.classify_issue(issue) + + # 监控新 PR 并审查 + prs = self.get_new_prs() + for pr in prs: + self.review_pr(pr) + + def automated_review(self): + """自动化审查""" + # 获取待审查的 PR + pending_prs = self.get_pending_prs() + + for pr in pending_prs: + review_result = self.analyze_pr(pr) + self.submit_review(pr, review_result) +``` + +## 最佳实践 + +### 1. 工作流选择 +- **项目创建**: 使用 workflow-repo-setup +- **日常维护**: 使用 workflow-issue-triage 和 workflow-pr-review +- **版本发布**: 使用 workflow-release-notes +- **团队管理**: 使用 workflow-sprint-report + +### 2. 执行顺序 +典型的执行顺序: +1. 项目初始化 → 2. Issue 管理 → 3. PR 审查 → 4. Release 发布 → 5. Sprint 报告 + +### 3. 错误处理 +```python +def safe_workflow_execution(workflow_func, *args, **kwargs): + """安全执行工作流""" + try: + return workflow_func(*args, **kwargs) + except Exception as e: + # 记录错误 + log_error(e) + # 尝试恢复 + return handle_workflow_error(e, workflow_func, *args, **kwargs) +``` + +### 4. 进度跟踪 +```python +class WorkflowProgress: + def __init__(self): + self.current_step = 0 + self.total_steps = 5 + self.completed_steps = [] + self.failed_steps = [] + + def update_progress(self, step_name, success=True): + if success: + self.completed_steps.append(step_name) + else: + self.failed_steps.append(step_name) + self.current_step += 1 + + def get_progress_report(self): + progress = self.current_step / self.total_steps * 100 + return { + 'progress': f'{progress:.1f}%', + 'completed': self.completed_steps, + 'failed': self.failed_steps + } +``` + +## 扩展工作流 + +### 自定义工作流 + +```python +# 创建自定义工作流 +def custom_workflow(owner, repo, custom_config): + """自定义工作流模板""" + + # 1. 预检查 + if not validate_environment(): + return False + + # 2. 执行自定义步骤 + for step in custom_config['steps']: + execute_step(step) + + # 3. 后处理 + cleanup_environment() + + return True +``` + +## 故障排除 + +### 常见问题 + +| 问题 | 解决方案 | +|------|----------| +| 权限不足 | 检查 Token 权限 | +| API 限制 | 添加重试机制 | +| 数据格式错误 | 验证输入数据 | +| 执行超时 | 增加超时时间 | + +## References + +- [workflow-issue-triage](../references/workflow-issue-triage.md) — Issue 分类 +- [workflow-pr-review](../references/workflow-pr-review.md) — PR 审查 +- [workflow-release-notes](../references/workflow-release-notes.md) — Release Notes +- [workflow-repo-setup](../references/workflow-repo-setup.md) — 仓库初始化 +- [workflow-sprint-report](../references/workflow-sprint-report.md) — Sprint 报告 +- [gitlink-workflow](../SKILL.md) — 工作流总览 diff --git a/skills/gitlink-workflow/references/workflow-issue-triage.md b/skills/gitlink-workflow/references/workflow-issue-triage.md new file mode 100644 index 0000000..66b5339 --- /dev/null +++ b/skills/gitlink-workflow/references/workflow-issue-triage.md @@ -0,0 +1,313 @@ +# Workflow: Issue Triage(Issue 自动分类) + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **AI Agent 工作流**:此工作流专为 AI Agent 设计,用于自动化 Issue 分类和管理。 + +AI Agent 自动为新建的 Issue 添加标签和分类,提高项目管理效率。 + +## 工作流概述 + +Issue Triage 工作流通过分析 Issue 的标题和描述内容,自动为 Issue 分配合适的标签,帮助项目维护者更好地组织和管理 Issue。 + +## 适用场景 + +- **项目维护**:自动分类新提交的 Issue +- **标签管理**:确保 Issue 有正确的分类标签 +- **优先级排序**:基于分类快速识别高优先级 Issue +- **团队协作**:减少手动分类工作量,提高效率 + +## 工作流步骤 + +### 步骤 1:获取未标记的 Issue 列表 + +```bash +# 获取所有开放的 Issue +gitlink-cli issue +list --state open --format json + +# 筛选出没有标签的 Issue +gitlink-cli issue +list --state open --format json | \ + jq '.data.issues[] | select(.issue_tags == null or .issue_tags == [])' +``` + +### 步骤 2:分析 Issue 内容 + +```bash +# 获取特定 Issue 的详细信息 +gitlink-cli issue +view --id 123 --format json + +# 分析标题和描述 +gitlink-cli issue +view --id 123 --format json | \ + jq '{subject: .data.subject, description: .data.description}' +``` + +### 步骤 3:智能分类 + +基于 Issue 内容的分析,应用以下分类规则: + +**Bug 分类规则**: +- 标题/描述包含关键词:`bug`、`错误`、`失败`、`异常`、`crash`、`issue`、`problem` +- 行为模式:描述功能失效或异常行为 +- 示例:`登录时遇到错误`、`页面加载失败` + +**Feature 分类规则**: +- 标题/描述包含关键词:`feature`、`新增`、`建议`、`request`、`enhancement`、`improve` +- 行为模式:建议新功能或改进 +- 示例:`添加用户权限管理`、`建议支持暗色主题` + +**Question 分类规则**: +- 标题/描述包含关键词:`question`、`如何`、`怎么`、`how`、`帮助`、`help`、`疑问` +- 行为模式:询问使用方法或寻求帮助 +- 示例:`如何配置环境变量`、`怎么部署到服务器` + +**Documentation 分类规则**: +- 标题/描述包含关键词:`doc`、`文档`、`README`、`tutorial`、`guide`、`example` +- 行为模式:与文档相关的问题或建议 +- 示例:`更新安装文档`、`添加使用示例` + +### 步骤 4:添加标签 + +```bash +# 获取项目的标签列表 +gitlink-cli api GET /:owner/:repo/issue_tags --format json + +# 为 Issue 添加标签 +gitlink-cli api POST /:owner/:repo/issues/123 --body \ + '{"issue_tag_ids":[1, 2]}' + +# 添加单个标签 +gitlink-cli api POST /:owner/:repo/issues/123 --body \ + '{"issue_tag_ids":[1]}' +``` + +## 完整工作流示例 + +```bash +#!/bin/bash + +# Issue Triage 自动化脚本 + +OWNER="myuser" +REPO="myproject" + +# 1. 获取所有开放的 Issue +ISSUES=$(gitlink-cli issue +list --owner $OWNER --repo $REPO --state open --format json) + +# 2. 遍历每个 Issue +echo "$ISSUES" | jq -c '.data.issues[]' | while read -r issue; do + ISSUE_ID=$(echo "$issue" | jq -r '.id') + SUBJECT=$(echo "$issue" | jq -r '.subject') + DESCRIPTION=$(echo "$issue" | jq -r '.description') + TAGS=$(echo "$issue" | jq -r '.issue_tags // []') + + # 跳过已有标签的 Issue + if [ "$TAGS" != "[]" ]; then + echo "Issue $ISSUE_ID 已有标签,跳过" + continue + fi + + echo "分析 Issue $ISSUE_ID: $SUBJECT" + + # 分析内容并确定标签 + TAG_IDS=() + CONTENT="$SUBJECT $DESCRIPTION" + + # 分类逻辑 + if echo "$CONTENT" | grep -iqE "bug|错误|失败|异常|crash|issue|problem"; then + TAG_IDS+=("1") # 假设 1 是 bug 标签 + echo " → 分类为: bug" + fi + + if echo "$CONTENT" | grep -iqE "feature|新增|建议|request|enhancement|improve"; then + TAG_IDS+=("2") # 假设 2 是 enhancement 标签 + echo " → 分类为: enhancement" + fi + + if echo "$CONTENT" | grep -iqE "question|如何|怎么|how|帮助|help|疑问"; then + TAG_IDS+=("3") # 假设 3 是 question 标签 + echo " → 分类为: question" + fi + + if echo "$CONTENT" | grep -iqE "doc|文档|README|tutorial|guide|example"; then + TAG_IDS+=("4") # 假设 4 是 documentation 标签 + echo " → 分类为: documentation" + fi + + # 添加标签到 Issue + if [ ${#TAG_IDS[@]} -gt 0 ]; then + echo " → 为 Issue $ISSUE_ID 添加标签: ${TAG_IDS[*]}" + # 实际执行时取消注释 + # gitlink-cli api POST "/$OWNER/$REPO/issues/$ISSUE_ID" --body \ + # "{\"issue_tag_ids\":[${TAG_IDS[*]}]}" + else + echo " → 无法自动分类,需要人工处理" + fi + + echo "" +done +``` + +## AI Agent 集成示例 + +Claude Code 等 AI Agent 可以直接执行此工作流: + +```python +# AI Agent 执行 Issue Triage +def issue_triage(owner, repo): + """AI Agent 自动分类 Issue""" + + # 1. 获取开放的 Issue + issues = gitlink_cli_issue_list(owner, repo, state="open") + + for issue in issues: + # 2. 跳过已有标签的 + if issue.get('issue_tags'): + continue + + # 3. AI 分析内容 + content = f"{issue['subject']} {issue.get('description', '')}" + classification = analyze_issue_content(content) + + # 4. 添加标签 + if classification: + add_issue_tags(owner, repo, issue['id'], classification) + +def analyze_issue_content(content): + """AI 分析 Issue 内容""" + # 使用 AI 模型分析文本 + labels = [] + + if any(word in content.lower() for word in ['bug', 'error', 'fail']): + labels.append('bug') + + if any(word in content.lower() for word in ['feature', 'enhancement']): + labels.append('enhancement') + + return labels +``` + +## 高级分类策略 + +### 多标签分类 +一个 Issue 可以有多个标签: + +```bash +# 同时添加多个标签 +gitlink-cli api POST /:owner/:repo/issues/123 --body \ + '{"issue_tag_ids":[1, 2, 5]}' + +# 示例:既严重又是功能请求 +# bug + enhancement + high-priority +``` + +### 优先级分类 +基于紧急程度添加优先级标签: + +**高优先级关键词**: +- `urgent`、`紧急`、`严重`、`critical`、`blocking`、`阻塞` + +**中优先级关键词**: +- `moderate`、`中等`、`normal`、`常规` + +**低优先级关键词**: +- `low`、`较低`、`minor`、`次要`、`nice-to-have` + +### 复杂度分类 +基于实现难度分类: + +**简单**: +- 关键词:`简单`、`easy`、`quick`、`minor` +- 预估时间:1-2 天 + +**中等**: +- 关键词:`中等`、`moderate`、`normal` +- 预估时间:3-7 天 + +**复杂**: +- 关键词:`复杂`、`complex`、`hard`、`major`、`重构` +- 预估时间:8+ 天 + +## 自定义分类规则 + +根据项目特点定制分类规则: + +```bash +# Web 项目特定分类 +WEB_KEYWORDS=("前端" "frontend" "UI" "界面" "页面") +if grep -qE "${WEB_KEYWORDS[*]}" <<< "$CONTENT"; then + TAG_IDS+=("10") # frontend 标签 +fi + +# 后端项目特定分类 +BACKEND_KEYWORDS=("后端" "backend" "API" "接口" "数据库") +if grep -qE "${BACKEND_KEYWORDS[*]}" <<< "$CONTENT"; then + TAG_IDS+=("11") # backend 标签 +fi + +# DevOps 相关分类 +DEVOPS_KEYWORDS=("部署" "deploy" "CI" "CD" "Docker" "Kubernetes") +if grep -qE "${DEVOPS_KEYWORDS[*]}" <<< "$CONTENT"; then + TAG_IDS+=("12") # devops 标签 +fi +``` + +## 错误处理 + +常见问题处理: + +| 问题 | 原因 | 解决方案 | +|------|------|----------| +| 标签 ID 不存在 | 标签未创建 | 先创建项目标签 | +| 权限不足 | 无修改 Issue 权限 | 联系项目管理员 | +| 分类不准确 | 关键词匹配失败 | 优化分类规则或人工审核 | + +## 质量保证 + +确保分类质量的措施: + +1. **定期审查**:定期审查自动分类结果 +2. **反馈学习**:根据反馈调整分类规则 +3. **人工确认**:对不确定的分类进行人工确认 +4. **规则优化**:持续优化关键词匹配规则 + +## 最佳实践 + +1. **渐进式部署**:先小范围测试,再全面应用 +2. **规则透明**:记录分类规则,便于团队理解和调整 +3. **性能监控**:监控分类准确率和效率 +4. **用户反馈**:收集用户反馈,持续改进 + +## 扩展功能 + +### 自动分配 +基于分类自动分配给合适的开发者: + +```bash +# Bug 分配给核心开发者 +if [[ " ${TAG_IDS[@]} " =~ " 1 " ]]; then + ASSIGNEE="senior_developer" +fi + +# 文档问题分配给技术写作 +if [[ " ${TAG_IDS[@]} " =~ " 4 " ]]; then + ASSIGNEE="tech_writer" +fi +``` + +### 自动设置优先级 +基于分类和关键词自动设置优先级: + +```bash +# 严重 bug 设置为高优先级 +if [[ " ${TAG_IDS[@]} " =~ " 1 " ]] && echo "$CONTENT" | grep -iq "严重"; then + PRIORITY_ID="1" # 高优先级 +fi +``` + +## References + +- [workflow-pr-review](workflow-pr-review.md) — PR 审查工作流 +- [workflow-release-notes](workflow-release-notes.md) — Release Notes 生成 +- [gitlink-workflow](../SKILL.md) — 工作流总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 +- [issue +list](../../gitlink-issue/references/gitlink-issue-list.md) — Issue 列表 +- [issue +view](../../gitlink-issue/references/gitlink-issue-view.md) — 查看 Issue diff --git a/skills/gitlink-workflow/references/workflow-pr-review.md b/skills/gitlink-workflow/references/workflow-pr-review.md new file mode 100644 index 0000000..1faed03 --- /dev/null +++ b/skills/gitlink-workflow/references/workflow-pr-review.md @@ -0,0 +1,397 @@ +# Workflow: PR Review(代码审查辅助) + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **AI Agent 工作流**:此工作流专为 AI Agent 设计,用于辅助代码审查。 + +AI Agent 获取 PR 变更内容,分析代码质量,自动添加 Review 评论,提高代码审查效率。 + +## 工作流概述 + +PR Review 工作流通过分析 Pull Request 的代码变更,自动识别潜在问题、提出改进建议,并生成结构化的审查意见。 + +## 适用场景 + +- **代码审查**:自动化 PR 初步审查 +- **质量检查**:检查代码质量和规范合规性 +- **安全审查**:识别潜在的安全问题 +- **性能分析**:评估性能相关代码变更 +- **文档检查**:验证代码注释和文档完整性 + +## 工作流步骤 + +### 步骤 1:获取 PR 详情 + +```bash +# 获取 PR 基本信息 +gitlink-cli pr +view --id 42 --format json + +# 提取关键信息 +PR_INFO=$(gitlink-cli pr +view --id 42 --format json | jq '.data') +PR_TITLE=$(echo "$PR_INFO" | jq -r '.title') +PR_AUTHOR=$(echo "$PR_INFO" | jq -r '.author.login') +SOURCE_BRANCH=$(echo "$PR_INFO" | jq -r '.head_ref') +TARGET_BRANCH=$(echo "$PR_INFO" | jq -r '.base_ref') +``` + +### 步骤 2:获取变更文件列表 + +```bash +# 获取 PR 变更的文件列表 +gitlink-cli pr +files --id 42 --format json + +# 分析文件变更 +FILES_CHANGED=$(gitlink-cli pr +files --id 42 --format json | \ + jq '.data.files[] | + {filename: .filename, + status: .status, + additions: .additions, + deletions: .deletions}') +``` + +### 步骤 3:获取代码差异 + +```bash +# 获取 PR 的完整代码差异 +gitlink-cli pr +diff --id 42 --format json + +# 提取特定文件的差异 +gitlink-cli pr +diff --id 42 --format json | \ + jq '.data.diff | split("diff --git")' +``` + +### 步骤 4:代码质量分析 + +分析代码变更的多个维度: + +**安全性分析**: +```bash +# 检查敏感信息泄露 +if echo "$DIFF" | grep -iE "password|secret|api_key|token"; then + SECURITY_ISSUES+=("可能包含敏感信息") +fi + +# 检查 SQL 注入风险 +if echo "$DIFF" | grep -iE "SELECT.*FROM.*WHERE.*\$"; then + SECURITY_ISSUES+=("可能的 SQL 注入风险") +fi +``` + +**代码规范检查**: +```bash +# 检查代码风格 +if echo "$DIFF" | grep -P "\t"; then + STYLE_ISSUES+=("包含 Tab 字符,建议使用空格") +fi + +# 检查长行 +if echo "$DIFF" | grep ".\{120,\}"; then + STYLE_ISSUES+=("包含超过 120 字符的长行") +fi +``` + +**性能分析**: +```bash +# 检查可能的性能问题 +if echo "$DIFF" | grep -iE "N\+1|SELECT.*\*|foreach.*query"; then + PERF_ISSUES+=("可能的 N+1 查询问题") +fi +``` + +### 步骤 5:生成 Review 评论 + +```bash +# 生成结构化的 Review 评论 +REVIEW_BODY="# 🔍 代码审查结果 + +## ✅ 优点 +- 代码结构清晰 +- 逻辑正确 +- 遵循项目规范 + +## ⚠️ 需要改进 +${STYLE_ISSUES[@]+($(printf -- "- %s\n" "${STYLE_ISSUES[@]}"))} + +## 🔒 安全问题 +${SECURITY_ISSUES[@]+($(printf -- "- %s\n" "${SECURITY_ISSUES[@]}"))} + +## 🚀 性能建议 +${PERF_ISSUES[@]+($(printf -- "- %s\n" "${PERF_ISSUES[@]}"))} + +## 📝 总体评价 +代码整体质量良好,建议修改上述问题后合并。" + +# 添加 Review 评论 +gitlink-cli api POST /:owner/:repo/pulls/42/reviews --body \ + "{\"body\":\"$REVIEW_BODY\",\"event\":\"COMMENT\"}" +``` + +## 完整工作流示例 + +```bash +#!/bin/bash + +# PR Review 自动化脚本 + +PR_ID=$1 +OWNER="myuser" +REPO="myproject" + +echo "开始审查 PR #$PR_ID..." + +# 1. 获取 PR 详情 +PR_INFO=$(gitlink-cli pr +view --owner $OWNER --repo $REPO --id $PR_ID --format json) +PR_TITLE=$(echo "$PR_INFO" | jq -r '.data.title') +PR_AUTHOR=$(echo "$PR_INFO" | jq -r '.data.author.login') +ADDITIONS=$(echo "$PR_INFO" | jq -r '.data.additions') +DELETIONS=$(echo "$PR_INFO" | jq -r '.data.deletions') + +echo "PR 标题: $PR_TITLE" +echo "PR 作者: $PR_AUTHOR" +echo "代码变更: +$ADDITIONS -$DELETIONS" + +# 2. 获取变更文件 +FILES=$(gitlink-cli pr +files --owner $OWNER --repo $REPO --id $PR_ID --format json) + +# 3. 获取代码差异 +DIFF=$(gitlink-cli pr +diff --owner $OWNER --repo $REPO --id $PR_ID --format json | \ + jq -r '.data.diff') + +# 4. 分析代码 +ISSUES=() +SUGGESTIONS=() + +# 安全性检查 +if echo "$DIFF" | grep -iE "password|secret|api_key|token.*="; then + ISSUES+=("🔒 安全:可能包含硬编码的敏感信息") +fi + +# 代码规范检查 +if echo "$DIFF" | grep -P "\t"; then + SUGGESTIONS+=("📝 规范:建议使用空格代替 Tab") +fi + +# 性能检查 +if echo "$DIFF" | grep -iE "SELECT.*\*.*FROM"; then + SUGGESTIONS+=("🚀 性能:建议明确指定字段而不是使用 *") +fi + +# 5. 生成 Review 评论 +if [ ${#ISSUES[@]} -eq 0 ] && [ ${#SUGGESTIONS[@]} -eq 0 ]; then + REVIEW_BODY="# ✅ 审查通过 + +代码质量良好,没有发现明显问题。可以合并。" + EVENT="APPROVE" +else + REVIEW_BODY="# 🔍 代码审查结果 + +## PR 信息 +- **标题**: $PR_TITLE +- **作者**: $PR_AUTHOR +- **变更**: +$ADDITIONS -$DELETIONS 行 + +## ❌ 需要修复 +$(printf -- "- %s\n" "${ISSUES[@]}") + +## 💡 改进建议 +$(printf -- "- %s\n" "${SUGGESTIONS[@]}") + +## 📋 后续步骤 +1. 修复上述问题 +2. 确保所有测试通过 +3. 更新相关文档" + EVENT="REQUEST_CHANGES" +fi + +# 6. 提交 Review +echo "提交 Review 评论..." +gitlink-cli api POST "/$OWNER/$REPO/pulls/$PR_ID/reviews" --body \ + "{\"body\":\"$REVIEW_BODY\",\"event\":\"$EVENT\"}" + +echo "审查完成!" +``` + +## AI Agent 集成示例 + +Claude Code 等 AI Agent 可以深度集成此工作流: + +```python +# AI Agent 执行 PR Review +def pr_review(owner, repo, pr_id): + """AI Agent 自动代码审查""" + + # 1. 获取 PR 信息 + pr_info = get_pr_details(owner, repo, pr_id) + files_changed = get_pr_files(owner, repo, pr_id) + diff_content = get_pr_diff(owner, repo, pr_id) + + # 2. AI 分析代码 + review_results = { + 'security': analyze_security(diff_content), + 'performance': analyze_performance(diff_content), + 'style': analyze_code_style(diff_content), + 'documentation': analyze_documentation(files_changed), + 'testing': analyze_test_coverage(files_changed) + } + + # 3. 生成审查意见 + review_comment = generate_review_comment(pr_info, review_results) + + # 4. 提交 Review + submit_review(owner, repo, pr_id, review_comment, review_results) + +def analyze_security(diff_content): + """AI 安全性分析""" + issues = [] + + # 检查常见安全问题 + security_patterns = { + 'hardcoded_secrets': r'password\s*=\s*["\'].*["\']', + 'sql_injection': r'SELECT.*FROM.*WHERE.*\${', + 'xss_risk': r'innerHTML\s*=', + 'command_injection': r'system\(|exec\(.*\$' + } + + for issue_name, pattern in security_patterns.items(): + if re.search(pattern, diff_content, re.IGNORECASE): + issues.append({ + 'type': 'security', + 'severity': 'high', + 'issue': issue_name, + 'description': f'检测到 {issue_name} 风险' + }) + + return issues + +def generate_review_comment(pr_info, review_results): + """AI 生成结构化审查意见""" + comment = f"""# 🔍 AI 代码审查报告 + +## PR 概览 +- **标题**: {pr_info['title']} +- **作者**: {pr_info['author']} +- **变更**: +{pr_info['additions']} -{pr_info['deletions']} 行 +- **文件数**: {len(pr_info['files'])} + +## 🔒 安全审查 +""" + + if review_results['security']: + for issue in review_results['security']: + comment += f"- ❌ **{issue['issue']}**: {issue['description']}\n" + else: + comment += "✅ 未发现安全问题\n" + + comment += "\n## 🚀 性能审查\n" + # 类似地添加其他审查结果... + + return comment +``` + +## 审查维度 + +### 1. 安全性审查 +- **敏感信息泄露**:检查硬编码的密码、API 密钥 +- **注入攻击**:SQL 注入、命令注入、XSS 风险 +- **权限控制**:检查权限验证逻辑 +- **数据验证**:输入验证和输出编码 + +### 2. 性能审查 +- **数据库查询**:N+1 查询、缺少索引 +- **内存使用**:内存泄漏、大对象处理 +- **算法复杂度**:时间复杂度和空间复杂度 +- **缓存策略**:缓存命中率和使用合理性 + +### 3. 代码质量审查 +- **代码规范**:命名规范、格式风格 +- **代码结构**:模块化、可读性、可维护性 +- **错误处理**:异常处理完整性 +- **注释文档**:代码注释和文档质量 + +### 4. 测试审查 +- **测试覆盖**:单元测试和集成测试 +- **测试质量**:测试用例的有效性 +- **边界条件**:边界值和异常情况测试 + +### 5. 文档审查 +- **API 文档**:接口文档完整性 +- **用户文档**:用户指南更新 +- **变更日志**:CHANGELOG 更新 + +## 审查决策 + +基于分析结果做出审查决策: + +**APPROVE(通过)**: +- 无严重问题 +- 建议性问题可接受 +- 测试覆盖充分 + +**REQUEST_CHANGES(请求修改)**: +- 存在严重安全问题 +- 重要功能缺失 +- 测试覆盖不足 + +**COMMENT(评论)**: +- 一般性建议 +- 文档改进 +- 代码优化建议 + +## 自动化规则 + +常见问题的自动检测规则: + +```python +AUTO_REVIEW_RULES = { + 'security': { + 'hardcoded_password': { + 'pattern': r'password\s*=\s*["\'][^"\']{8,}["\']', + 'severity': 'high', + 'message': '检测到硬编码密码,请使用环境变量或配置文件' + }, + 'sql_injection': { + 'pattern': r'SELECT.*FROM.*WHERE.*\$[a-z_]+', + 'severity': 'high', + 'message': '可能的 SQL 注入风险,请使用参数化查询' + } + }, + 'performance': { + 'n_plus_one': { + 'pattern': r'for\s+\$.*\{\s*.*SELECT', + 'severity': 'medium', + 'message': '可能的 N+1 查询问题,考虑使用预加载' + }, + 'missing_index': { + 'pattern': r'WHERE.*LIKE.*%.*%', + 'severity': 'low', + 'message': '前缀模糊搜索可能无法使用索引' + } + } +} +``` + +## 最佳实践 + +1. **逐步审查**:先检查严重问题,再检查一般问题 +2. **建设性反馈**:提供具体的改进建议 +3. **平衡严格**:平衡代码质量和开发效率 +4. **学习改进**:从审查中学习,提高代码质量 +5. **团队协作**:与开发者沟通,达成共识 + +## 质量保证 + +确保审查质量: + +1. **双重检查**:重要 PR 进行二次审查 +2. **审查标准**:建立统一的审查标准 +3. **审查培训**:培训审查人员 +4. **反馈收集**:收集对审查质量的反馈 +5. **持续改进**:优化审查流程和规则 + +## References + +- [workflow-issue-triage](workflow-issue-triage.md) — Issue 分类工作流 +- [workflow-release-notes](workflow-release-notes.md) — Release Notes 生成 +- [gitlink-workflow](../SKILL.md) — 工作流总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 +- [pr +view](../../gitlink-pr/references/gitlink-pr-view.md) — 查看 PR +- [pr +files](../../gitlink-pr/references/gitlink-pr-files.md) — 查看 PR 文件变更 diff --git a/skills/gitlink-workflow/references/workflow-release-notes.md b/skills/gitlink-workflow/references/workflow-release-notes.md new file mode 100644 index 0000000..91d3438 --- /dev/null +++ b/skills/gitlink-workflow/references/workflow-release-notes.md @@ -0,0 +1,513 @@ +# Workflow: Release Notes 生成 + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **AI Agent 工作流**:此工作流专为 AI Agent 设计,用于自动生成版本发布说明。 + +AI Agent 从提交历史、Issue 和 PR 数据自动生成结构化的 Release Notes,确保发布文档的完整性和准确性。 + +## 工作流概述 + +Release Notes 生成工作流自动收集版本间的所有变更信息,整理成结构化的发布说明,包含新功能、Bug 修复、破坏性变更等重要信息。 + +## 适用场景 + +- **版本发布**:为每个新版本生成发布说明 +- **变更追踪**:追踪版本间的具体变更 +- **用户沟通**:向用户清晰传达版本更新内容 +- **历史记录**:维护项目变更历史 + +## 工作流步骤 + +### 步骤 1:确定版本范围 + +```bash +# 获取最新标签 +LATEST_TAG=$(gitlink-cli release +list --format json | \ + jq -r '.data.releases[0].tag_name') + +# 确定新版本号 +NEW_TAG="v1.2.0" + +# 或者获取两个标签之间的差异 +BASE_TAG="v1.1.0" +HEAD_TAG="v1.2.0" +``` + +### 步骤 2:获取提交历史 + +```bash +# 获取版本间的提交比较 +gitlink-cli api GET /:owner/:repo/compare/$BASE_TAG...$HEAD_TAG --format json + +# 提取提交信息 +COMMITS=$(gitlink-cli api GET /:owner/:repo/compare/$BASE_TAG...$HEAD_TAG --format json | \ + jq '.data.commits[] | + {message: .commit.message, + author: .commit.author.name, + date: .commit.author.date, + sha: .sha}') +``` + +### 步骤 3:获取已关闭的 Issue + +```bash +# 获取已关闭的 Issue +CLOSED_ISSUES=$(gitlink-cli issue +list --state closed --format json | \ + jq '.data.issues[] | + select(.closed_at >= "'$START_DATE'") | + {id: .id, + subject: .subject, + labels: [.issue_tags[].name], + closed_at: .closed_at}') +``` + +### 步骤 4:获取合并的 PR + +```bash +# 获取已合并的 PR +MERGED_PRS=$(gitlink-cli pr +list --state merged --format json | \ + jq '.data.prs[] | + select(.merged_at >= "'$START_DATE'") | + {id: .id, + title: .title, + number: .number, + author: .author.login, + merged_at: .merged_at}') +``` + +### 步骤 5:分类和整理变更 + +```bash +# 按变更类型分类 +FEATURES=() +BUG_FIXES=() +ENHANCEMENTS=() +BREAKING_CHANGES=() + +# 分析 Issue 标签分类 +while read -r issue; do + SUBJECT=$(echo "$issue" | jq -r '.subject') + LABELS=$(echo "$issue" | jq -r '.labels[]') + + if echo "$LABELS" | grep -q "feature"; then + FEATURES+=("$SUBJECT") + elif echo "$LABELS" | grep -q "bug"; then + BUG_FIXES+=("$SUBJECT") + elif echo "$LABELS" | grep -q "enhancement"; then + ENHANCEMENTS+=("$SUBJECT") + fi +done <<< "$CLOSED_ISSUES" + +# 分析提交信息 +while read -r commit; do + MESSAGE=$(echo "$commit" | jq -r '.message') + + if echo "$MESSAGE" | grep -iq "BREAKING"; then + BREAKING_CHANGES+=("$MESSAGE") + fi +done <<< "$COMMITS" +``` + +### 步骤 6:生成 Release Notes + +```bash +# 生成结构化的 Release Notes +RELEASE_NOTES="# 🚀 Release Notes for $NEW_TAG + +## 📝 What's Changed + +### ✨ New Features +$(for feature in "${FEATURES[@]}"; do + echo "- $feature" +done) + +### 🐛 Bug Fixes +$(for fix in "${BUG_FIXES[@]}"; do + echo "- $fix" +done) + +### 🔧 Enhancements +$(for enhancement in "${ENHANCEMENTS[@]}"; do + echo "- $enhancement" +done) + +### ⚠️ Breaking Changes +$(for breaking in "${BREAKING_CHANGES[@]}"; do + echo "- $breaking" +done)" + +# 创建 Release +gitlink-cli release +create --tag $NEW_TAG --name "$NEW_TAG" --body "$RELEASE_NOTES" +``` + +## 完整工作流示例 + +```bash +#!/bin/bash + +# Release Notes 自动生成脚本 + +OWNER="myuser" +REPO="myproject" +NEW_VERSION=$1 + +if [ -z "$NEW_VERSION" ]; then + echo "使用方法: $0 <version>" + exit 1 +fi + +echo "为版本 $NEW_VERSION 生成 Release Notes..." + +# 1. 获取上一个版本 +PREV_VERSION=$(gitlink-cli release +list --owner $OWNER --repo $REPO --format json | \ + jq -r '.data.releases[0].tag_name') + +echo "上一个版本: $PREV_VERSION" +echo "新版本: $NEW_VERSION" + +# 2. 获取提交比较 +COMPARE_DATA=$(gitlink-cli api GET "/$OWNER/$REPO/compare/$PREV_VERSION...$NEW_VERSION" --format json) +COMMITS=$(echo "$COMPARE_DATA" | jq -r '.data.commits') + +# 3. 获取已关闭的 Issue +ISSUES=$(gitlink-cli issue +list --owner $OWNER --repo $REPO --state closed --format json | \ + jq '.data.issues[]') + +# 4. 获取已合并的 PR +PRS=$(gitlink-cli pr +list --owner $OWNER --repo $REPO --state merged --format json | \ + jq '.data.prs[]') + +# 5. 分析变更数据 +FEATURE_COUNT=0 +BUG_FIX_COUNT=0 +ENHANCEMENT_COUNT=0 +BREAKING_COUNT=0 + +# 分析 Issue +FEATURES=$(echo "$ISSUES" | jq -r 'select(.issue_tags[]?.name == "feature") | "- \(.subject) (#\(.id))"') +BUG_FIXES=$(echo "$ISSUES" | jq -r 'select(.issue_tags[]?.name == "bug") | "- \(.subject) (#\(.id))"') +ENHANCEMENTS=$(echo "$ISSUES" | jq -r 'select(.issue_tags[]?.name == "enhancement") | "- \(.subject) (#\(.id))"') + +# 分析提交中的破坏性变更 +BREAKING_CHANGES=$(echo "$COMMITS" | jq -r 'select(.commit.message | contains("BREAKING")) | "- \(.commit.message | split("\n")[0])"') + +# 统计数量 +FEATURE_COUNT=$(echo "$FEATURES" | grep -c "^-" || echo "0") +BUG_FIX_COUNT=$(echo "$BUG_FIXES" | grep -c "^-" || echo "0") +ENHANCEMENT_COUNT=$(echo "$ENHANCEMENTS" | grep -c "^-" || echo "0") +BREAKING_COUNT=$(echo "$BREAKING_CHANGES" | grep -c "^-" || echo "0") + +# 6. 生成 Release Notes +RELEASE_NOTES="# 🎉 Release $NEW_VERSION + +## 📊 变更统计 +- **新功能**: $FEATURE_COUNT 个 +- **Bug 修复**: $BUG_FIX_COUNT 个 +- **功能改进**: $ENHANCEMENT_COUNT 个 +- **破坏性变更**: $BREAKING_COUNT 个 + +## ✨ 新功能 +$FEATURES + +## 🐛 Bug 修复 +$BUG_FIXES + +## 🔧 功能改进 +$ENHANCEMENTS + +## ⚠️ 破坏性变更 +$BREAKING_CHANGES + +## 🙏 贡献者 +感谢所有参与此版本开发的贡献者! + +## 📥 安装 +\`\`\`bash +npm install $OWNER/$REPO@$NEW_VERSION +\`\`\` + +## 📚 文档 +完整文档请查看: https://www.gitlink.org.cn/$OWNER/$REPO/wiki + +--- +**完整变更日志**: https://www.gitlink.org.cn/$OWNER/$REPO/compare/$PREV_VERSION...$NEW_VERSION" + +# 7. 创建 Release +echo "创建 Release $NEW_VERSION..." +gitlink-cli release +create --owner $OWNER --repo $REPO \ + --tag $NEW_VERSION --name "$NEW_VERSION" --body "$RELEASE_NOTES" + +echo "Release $NEW_VERSION 创建完成!" +``` + +## AI Agent 集成示例 + +Claude Code 等 AI Agent 可以深度集成此工作流: + +```python +# AI Agent 生成 Release Notes +def generate_release_notes(owner, repo, new_version): + """AI Agent 自动生成发布说明""" + + # 1. 获取版本信息 + prev_version = get_latest_release(owner, repo) + commits = compare_revisions(owner, repo, prev_version, new_version) + issues = get_closed_issues(owner, repo, since=prev_version) + prs = get_merged_prs(owner, repo, since=prev_version) + + # 2. AI 分析变更 + changes = analyze_changes(commits, issues, prs) + + # 3. 生成发布说明 + release_notes = format_release_notes(new_version, changes, prev_version) + + # 4. 创建 Release + create_release(owner, repo, new_version, release_notes) + + return release_notes + +def analyze_changes(commits, issues, prs): + """AI 智能分析变更内容""" + + changes = { + 'features': [], + 'bug_fixes': [], + 'enhancements': [], + 'breaking_changes': [], + 'contributors': set(), + 'performance_improvements': [], + 'security_fixes': [] + } + + # 分析 Issue + for issue in issues: + labels = [label['name'] for label in issue.get('issue_tags', [])] + subject = issue['subject'] + + if 'feature' in labels: + changes['features'].append(format_issue_reference(issue)) + elif 'bug' in labels: + changes['bug_fixes'].append(format_issue_reference(issue)) + elif 'enhancement' in labels: + changes['enhancements'].append(format_issue_reference(issue)) + elif 'security' in labels: + changes['security_fixes'].append(format_issue_reference(issue)) + + # 分析提交信息 + for commit in commits: + message = commit['commit']['message'] + + # 使用 AI 分析提交消息 + analysis = analyze_commit_message(message) + + if analysis.get('breaking_change'): + changes['breaking_changes'].append(message) + elif analysis.get('performance'): + changes['performance_improvements'].append(message) + + # 收集贡献者 + changes['contributors'].add(commit['author']['name']) + + return changes + +def format_release_notes(version, changes, prev_version): + """AI 生成结构化发布说明""" + + notes = f"""# 🎉 Release {version} + +## 📊 变更统计 +- **新功能**: {len(changes['features'])} 个 +- **Bug 修复**: {len(changes['bug_fixes'])} 个 +- **功能改进**: {len(changes['enhancements'])} 个 +- **破坏性变更**: {len(changes['breaking_changes'])} 个 +""" + + if changes['features']: + notes += "\n## ✨ 新功能\n" + notes += "\n".join(f"- {feature}" for feature in changes['features']) + notes += "\n" + + if changes['bug_fixes']: + notes += "\n## 🐛 Bug 修复\n" + notes += "\n".join(f"- {fix}" for fix in changes['bug_fixes']) + notes += "\n" + + if changes['breaking_changes']: + notes += "\n## ⚠️ 破坏性变更\n" + notes += "\n".join(f"- {change}" for change in changes['breaking_changes']) + notes += "\n" + + if changes['contributors']: + notes += f"\n## 🙏 贡献者\n" + notes += ", ".join(sorted(changes['contributors'])) + notes += "\n" + + notes += f"\n---\n**完整变更日志**: https://www.gitlink.org.cn/{owner}/{repo}/compare/{prev_version}...{version}" + + return notes + +def analyze_commit_message(message): + """AI 分析提交消息""" + return { + 'breaking_change': bool(re.search(r'BREAKING|breaking|!', message)), + 'performance': bool(re.search(r'performance|优化|提升', message, re.I)), + 'security': bool(re.search(r'security|安全|漏洞', message, re.I)) + } +``` + +## Release Notes 模板 + +### 标准模板 + +```markdown +# 🎉 Release {VERSION} + +## 📊 变更统计 +- **新功能**: {FEATURE_COUNT} 个 +- **Bug 修复**: {BUG_FIX_COUNT} 个 +- **功能改进**: {ENHANCEMENT_COUNT} 个 +- **破坏性变更**: {BREAKING_COUNT} 个 + +## ✨ 新功能 +{FEATURES_LIST} + +## 🐛 Bug 修复 +{BUG_FIXES_LIST} + +## 🔧 功能改进 +{ENHANCEMENTS_LIST} + +## ⚠️ 破坏性变更 +{BREAKING_CHANGES_LIST} + +## 🙏 贡献者 +{CONTRIBUTORS_LIST} + +## 📥 安装 +```bash +# 使用 npm +npm install {PACKAGE}@{VERSION} + +# 使用 yarn +yarn add {PACKAGE}@{VERSION} + +# 使用 pnpm +pnpm add {PACKAGE}@{VERSION} +``` + +## 🔄 升级指南 +{UPGRADE_GUIDE} + +## 📚 文档 +完整文档请查看: https://www.gitlink.org.cn/{OWNER}/{REPO}/wiki + +--- +**完整变更日志**: https://www.gitlink.org.cn/{OWNER}/{REPO}/compare/{PREV_VERSION}...{VERSION} +``` + +### 简化模板 + +```markdown +# {VERSION} + +## 新增 +{FEATURES} + +## 修复 +{BUG_FIXES} + +## 改进 +{ENHANCEMENTS} + +## 贡献者 +{CONTRIBUTORS} + +## 链接 +- [完整变更](https://www.gitlink.org.cn/{OWNER}/{REPO}/compare/{PREV_VERSION}...{VERSION}) +- [问题追踪](https://www.gitlink.org.cn/{OWNER}/{REPO}/issues) +``` + +## 自动化分类规则 + +基于提交信息和 Issue 标签的自动分类: + +```python +RELEASE_CATEGORIES = { + 'features': { + 'labels': ['feature', 'enhancement'], + 'commit_keywords': ['feat:', 'add', 'new'], + 'icon': '✨', + 'title': '新功能' + }, + 'bug_fixes': { + 'labels': ['bug', 'fix'], + 'commit_keywords': ['fix:', 'bugfix'], + 'icon': '🐛', + 'title': 'Bug 修复' + }, + 'enhancements': { + 'labels': ['improvement', 'optimize'], + 'commit_keywords': ['improve:', 'optimize:', 'refactor:'], + 'icon': '🔧', + 'title': '功能改进' + }, + 'breaking_changes': { + 'labels': ['breaking', 'major'], + 'commit_keywords': ['BREAKING', 'breaking:', '!'], + 'icon': '⚠️', + 'title': '破坏性变更' + }, + 'security': { + 'labels': ['security', 'vulnerability'], + 'commit_keywords': ['security:', 'fix security'], + 'icon': '🔒', + 'title': '安全修复' + } +} +``` + +## 版本号规范 + +遵循语义化版本 (Semantic Versioning): + +``` +MAJOR.MINOR.PATCH + +MAJOR: 不兼容的 API 变更 +MINOR: 向后兼容的功能新增 +PATCH: 向后兼容的 Bug 修复 +``` + +版本号示例: +- `1.0.0` → `1.1.0`:新增功能 +- `1.1.0` → `1.1.1`:Bug 修复 +- `1.1.1` → `2.0.0`:破坏性变更 + +## 质量检查 + +发布前检查清单: + +- [ ] Release Notes 完整性检查 +- [ ] 变更统计准确性验证 +- [ ] 破坏性变更标识 +- [ ] 升级指南完整性 +- [ ] 文档链接正确性 +- [ ] 安装指令有效性 +- [ ] 贡献者列表完整性 + +## 最佳实践 + +1. **定期发布**:建立定期发布节奏 +2. **变更追踪**:确保所有变更都被记录 +3. **清晰分类**:使用明确的分类和标签 +4. **用户友好**:提供升级指南和迁移说明 +5. **版本规范**:遵循语义化版本规范 + +## References + +- [workflow-issue-triage](workflow-issue-triage.md) — Issue 分类工作流 +- [workflow-pr-review](workflow-pr-review.md) — PR 审查工作流 +- [gitlink-workflow](../SKILL.md) — 工作流总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 +- [release +create](../../gitlink-release/references/gitlink-release-create.md) — 创建 Release +- [release +list](../../gitlink-release/references/gitlink-release-list.md) — 列出 Release diff --git a/skills/gitlink-workflow/references/workflow-repo-setup.md b/skills/gitlink-workflow/references/workflow-repo-setup.md new file mode 100644 index 0000000..f887ff3 --- /dev/null +++ b/skills/gitlink-workflow/references/workflow-repo-setup.md @@ -0,0 +1,646 @@ +# Workflow: Repo Setup(仓库初始化) + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **AI Agent 工作流**:此工作流专为 AI Agent 设计,用于自动化仓库初始化设置。 + +AI Agent 自动创建新仓库并完成基础配置,包括分支保护、初始文档、Issue 模板等,确保新项目快速启动。 + +## 工作流概述 + +Repo Setup 工作流自动化创建新 GitLink 仓库,并进行标准化初始化配置,包括 README、LICENSE、分支保护、CI 配置等项目必需的设置。 + +## 适用场景 + +- **项目创建**:快速创建新的项目仓库 +- **标准化设置**:确保所有仓库配置一致 +- **模板应用**:应用组织或团队的项目模板 +- **批量创建**:批量创建多个相关项目 + +## 工作流步骤 + +### 步骤 1:创建仓库 + +```bash +# 创建新仓库 +gitlink-cli repo +create \ + --name my-awesome-project \ + --description "一个很棒的项目" \ + --private false + +# 或者创建私有仓库 +gitlink-cli repo +create \ + --name internal-project \ + --description "内部项目" \ + --private true +``` + +### 步骤 2:初始化本地仓库 + +```bash +# 本地初始化 +cd my-awesome-project +git init +git remote add gitlink https://www.gitlink.org.cn/username/my-awesome-project.git + +# 创建初始文件 +echo "# My Awesome Project" > README.md +echo "MIT License" > LICENSE +git add . +git commit -m "Initial commit" +git push -u gitlink master:master +``` + +### 步骤 3:设置分支保护 + +```bash +# 保护主分支 +gitlink-cli branch +protect \ + --owner username \ + --repo my-awesome-project \ + --name master + +# 如果使用 main 分支 +gitlink-cli branch +protect \ + --owner username \ + --repo my-awesome-project \ + --name main +``` + +### 步骤 4:创建配置文件 + +```bash +# 创建 .gitignore +cat > .gitignore << 'EOF' +# 依赖 +node_modules/ +vendor/ + +# 构建输出 +dist/ +build/ +*.log + +# IDE +.vscode/ +.idea/ + +# 环境变量 +.env +.env.local +EOF + +# 创建配置文件(根据项目类型) +if [ "$PROJECT_TYPE" = "node" ]; then + echo '{"name":"my-awesome-project","version":"1.0.0"}' > package.json +elif [ "$PROJECT_TYPE" = "python" ]; then + echo "[project]\nname = 'my-awesome-project'\nversion = '1.0.0'" > pyproject.toml +fi + +git add .gitignore package.json pyproject.toml +git commit -m "Add project configuration files" +git push gitlink master:master +``` + +### 步骤 5:创建 Issue 和 PR 模板 + +```bash +# 创建 Issue 模板 +cat > .github/ISSUE_TEMPLATE/bug_report.md << 'EOF' +--- +name: Bug 报告 +about: 报告项目中的问题 +title: '[Bug] ' +--- + +## Bug 描述 +简要描述遇到的问题。 + +## 复现步骤 +1. +2. +3. + +## 预期行为 +描述你期望发生的行为。 + +## 实际行为 +描述实际发生的行为。 + +## 环境 +- 操作系统: +- 版本: +- 其他信息: +EOF + +# 创建 PR 模板 +cat > .github/PULL_REQUEST_TEMPLATE.md << 'EOF' +## 变更描述 +简要描述这个 PR 的目的和内容。 + +## 变更类型 +- [ ] Bug 修复 +- [ ] 新功能 +- [ ] 功能改进 +- [ ] 文档更新 +- [ ] 性能优化 +- [ ] 代码重构 + +## 测试 +描述你如何测试这些变更: + +## 检查清单 +- [ ] 代码遵循项目规范 +- [ ] 已添加必要的测试 +- [ ] 已更新相关文档 +- [ ] 所有测试通过 +- [ ] 无合并冲突 +EOF + +git add .github/ +git commit -m "Add issue and PR templates" +git push gitlink master:master +``` + +### 步骤 6:创建初始 Issue + +```bash +# 创建项目初始化 Issue +gitlink-cli issue +create \ + --owner username \ + --repo my-awesome-project \ + --title "完成项目初始化" \ + --body "## 初始化任务清单 + +- [x] 创建仓库 +- [x] 添加 README.md +- [x] 添加 LICENSE +- [x] 设置分支保护 +- [x] 添加配置文件 +- [x] 创建 Issue 模板 +- [x] 创建 PR 模板 +- [ ] 配置 CI/CD +- [ ] 添加项目文档 +- [ ] 设置开发指南 + +## 下一步 +1. 配置 CI/CD 流程 +2. 编写项目文档 +3. 设置开发环境指南 +4. 创建贡献指南" +``` + +### 步骤 7:配置 CI/CD(可选) + +```bash +# 创建 CI 配置文件 +cat > .gitlab-ci.yml << 'EOF' +stages: + - test + - build + - deploy + +test: + stage: test + script: + - echo "Running tests..." + - npm test + +build: + stage: build + script: + - echo "Building..." + - npm run build + +deploy: + stage: deploy + script: + - echo "Deploying..." + - npm run deploy + only: + - master +EOF + +git add .gitlab-ci.yml +git commit -m "Add CI/CD configuration" +git push gitlink master:master +``` + +## 完整工作流示例 + +```bash +#!/bin/bash + +# 仓库初始化自动化脚本 + +PROJECT_NAME=$1 +PROJECT_DESC=$2 +IS_PRIVATE=${3:-false} +OWNER="username" + +if [ -z "$PROJECT_NAME" ]; then + echo "使用方法: $0 <project_name> [description] [private]" + exit 1 +fi + +echo "开始初始化项目: $PROJECT_NAME" + +# 1. 创建仓库 +echo "创建仓库..." +REPO_INFO=$(gitlink-cli repo +create \ + --name "$PROJECT_NAME" \ + --description "$PROJECT_DESC" \ + --private "$IS_PRIVATE" \ + --format json) + +if echo "$REPO_INFO" | jq -e '.ok' > /dev/null; then + echo "✅ 仓库创建成功" +else + echo "❌ 仓库创建失败" + exit 1 +fi + +# 2. 本地初始化 +echo "初始化本地仓库..." +mkdir -p "$PROJECT_NAME" +cd "$PROJECT_NAME" +git init +git remote add gitlink "https://www.gitlink.org.cn/$OWNER/$PROJECT_NAME.git" + +# 3. 创建基础文件 +echo "创建项目文件..." + +# README.md +cat > README.md << EOF +# $PROJECT_NAME + +$PROJECT_DESC + +## 快速开始 + +\`\`\`bash +# 安装依赖 +npm install + +# 开发模式运行 +npm run dev + +# 构建项目 +npm run build + +# 运行测试 +npm test +\`\`\` + +## 项目结构 + +\`\`\` +$PROJECT_NAME/ +├── src/ # 源代码 +├── tests/ # 测试文件 +├── docs/ # 文档 +├── scripts/ # 脚本 +└── package.json # 项目配置 +\`\`\` + +## 贡献指南 + +欢迎提交 Issue 和 Pull Request! + +## 许可证 + +MIT License +EOF + +# LICENSE +cat > LICENSE << 'EOF' +MIT License + +Copyright (c) 2026 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +EOF + +# package.json +cat > package.json << EOF +{ + "name": "$PROJECT_NAME", + "version": "1.0.0", + "description": "$PROJECT_DESC", + "main": "src/index.js", + "scripts": { + "dev": "echo 'Development mode'", + "build": "echo 'Building project'", + "test": "echo 'Running tests'", + "lint": "echo 'Linting code'" + }, + "keywords": [], + "author": "", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://www.gitlink.org.cn/$OWNER/$PROJECT_NAME.git" + } +} +EOF + +# .gitignore +cat > .gitignore << 'EOF' +node_modules/ +dist/ +build/ +*.log +.env +.env.local +.DS_Store +*.swp +*.swo +.vscode/ +.idea/ +coverage/ +.nyc_output/ +EOF + +# 创建目录结构 +mkdir -p src tests docs scripts + +# 4. 提交初始文件 +echo "提交初始文件..." +git add . +git commit -m "Initial commit" +git push -u gitlink master:master + +# 5. 设置分支保护 +echo "设置分支保护..." +gitlink-cli branch +protect \ + --owner "$OWNER" \ + --repo "$PROJECT_NAME" \ + --name master + +# 6. 创建项目模板 +echo "创建 Issue 模板..." +mkdir -p .github/ISSUE_TEMPLATE + +cat > .github/ISSUE_TEMPLATE/bug_report.md << 'EOF' +--- +name: Bug 报告 +about: 报告项目中的问题 +title: '[Bug] ' +--- + +## Bug 描述 +简要描述遇到的问题。 + +## 复现步骤 +1. +2. +3. + +## 预期行为 +描述你期望发生的行为。 + +## 实际行为 +描述实际发生的行为。 + +## 环境 +- 操作系统: +- 版本: +- 其他信息: +EOF + +# 7. 创建初始化 Issue +echo "创建初始化 Issue..." +gitlink-cli issue +create \ + --owner "$OWNER" \ + --repo "$PROJECT_NAME" \ + --title "完成项目初始化设置" \ + --body "## 项目初始化任务 + +### 基础配置 +- [x] 创建仓库 +- [x] 添加 README.md +- [x] 添加 LICENSE +- [x] 设置分支保护 +- [x] 添加配置文件 +- [x] 创建目录结构 + +### 下一步任务 +- [ ] 配置 CI/CD +- [ ] 编写项目文档 +- [ ] 设置开发指南 +- [ ] 创建贡献指南 +- [ ] 添加代码规范 +- [ ] 配置代码检查 + +## 开发环境设置 +\`\`\`bash +# 克隆仓库 +git clone https://www.gitlink.org.cn/$OWNER/$PROJECT_NAME.git + +# 安装依赖 +cd $PROJECT_NAME +npm install + +# 开发模式 +npm run dev +\`\`\` + +## 贡献流程 +1. Fork 本仓库 +2. 创建功能分支 (\`git checkout -b feature/AmazingFeature\`) +3. 提交更改 (\`git commit -m 'Add some AmazingFeature'\`) +4. 推送到分支 (\`git push origin feature/AmazingFeature\`) +5. 创建 Pull Request" + +echo "✅ 项目初始化完成!" +echo "" +echo "项目信息:" +echo " 名称: $PROJECT_NAME" +echo " 仓库: https://www.gitlink.org.cn/$OWNER/$PROJECT_NAME" +echo " 状态: $([ "$IS_PRIVATE" = "true" ] && echo "私有" || echo "公开")" +echo "" +echo "下一步:" +echo " 1. cd $PROJECT_NAME" +echo " 2. 配置开发环境" +echo " 3. 开始开发" +``` + +## AI Agent 集成示例 + +Claude Code 等 AI Agent 可以深度集成此工作流: + +```python +# AI Agent 仓库初始化 +def setup_repository(owner, repo_name, description, private=False): + """AI Agent 自动化仓库初始化""" + + # 1. 创建仓库 + repo = create_repository(owner, repo_name, description, private) + + # 2. 初始化项目结构 + project_structure = generate_project_structure(repo_name) + initialize_project_files(repo_name, project_structure) + + # 3. 配置分支保护 + protect_branch(owner, repo_name, 'master') + + # 4. 创建 Issue 模板 + create_issue_templates(owner, repo_name) + + # 5. 配置 CI/CD + setup_cicd(owner, repo_name, project_structure['type']) + + # 6. 创建初始化 Issue + create_setup_issue(owner, repo_name) + + return repo + +def generate_project_structure(repo_name): + """AI 生成项目结构""" + + # 分析项目名称和描述,确定项目类型 + project_type = analyze_project_type(repo_name) + + structures = { + 'node': { + 'directories': ['src', 'tests', 'docs', 'scripts'], + 'files': { + 'package.json': generate_package_json(repo_name), + '.gitignore': generate_gitignore('node'), + 'README.md': generate_readme(repo_name) + } + }, + 'python': { + 'directories': ['src', 'tests', 'docs', 'scripts'], + 'files': { + 'pyproject.toml': generate_pyproject(repo_name), + '.gitignore': generate_gitignore('python'), + 'README.md': generate_readme(repo_name) + } + } + } + + return structures.get(project_type, structures['node']) + +def create_issue_templates(owner, repo): + """创建 Issue 模板""" + + templates = { + 'bug_report.md': generate_bug_template(), + 'feature_request.md': generate_feature_template(), + 'question.md': generate_question_template() + } + + for template_name, content in templates.items(): + # 使用 API 创建模板文件 + create_file_via_api(owner, repo, + f'.github/ISSUE_TEMPLATE/{template_name}', + content) +``` + +## 项目模板 + +### 前端项目模板 + +```bash +# 创建前端项目结构 +create_frontend_project() { + mkdir -p src/{components,pages,hooks,utils} + mkdir -p public/{images,fonts} + mkdir -p tests/{unit,integration} + + # package.json + cat > package.json << 'EOF' +{ + "name": "my-frontend-project", + "version": "1.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "test": "vitest", + "lint": "eslint src/" + }, + "dependencies": { + "react": "^18.0.0" + } +} +EOF +} +``` + +### 后端项目模板 + +```bash +# 创建后端项目结构 +create_backend_project() { + mkdir -p src/{controllers,models,routes,middleware} + mkdir -p tests/{unit,integration} + mkdir -p config + mkdir -m migrations + + # package.json + cat > package.json << 'EOF' +{ + "name": "my-backend-project", + "version": "1.0.0", + "scripts": { + "start": "node src/server.js", + "dev": "nodemon src/server.js", + "test": "jest", + "migrate": "knex migrate:latest" + }, + "dependencies": { + "express": "^4.18.0", + "knex": "^2.0.0" + } +} +EOF +} +``` + +## 配置检查清单 + +仓库初始化完成后检查: + +- [ ] 仓库创建成功 +- [ ] README.md 完整 +- [ ] LICENSE 文件存在 +- [ ] 分支保护已设置 +- [ ] .gitignore 配置正确 +- [ ] Issue 模板创建 +- [ ] PR 模板创建 +- [ ] CI/CD 配置(可选) +- [ ] 初始化 Issue 已创建 +- [ ] 本地仓库可正常推送 + +## 最佳实践 + +1. **标准化模板**:使用统一的项目模板 +2. **配置管理**:统一配置文件格式 +3. **文档完整**:确保 README 和文档完整 +4. **安全设置**:合理设置分支保护 +5. **CI/CD 配置**:早期建立 CI/CD 流程 + +## References + +- [workflow-issue-triage](workflow-issue-triage.md) — Issue 分类工作流 +- [workflow-sprint-report](workflow-sprint-report.md) — Sprint 报告工作流 +- [gitlink-workflow](../SKILL.md) — 工作流总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 +- [repo +create](../../gitlink-repo/references/repo-create.md) — 创建仓库 +- [branch +protect](../../gitlink-branch/references/branch-protect.md) — 保护分支 diff --git a/skills/gitlink-workflow/references/workflow-sprint-report.md b/skills/gitlink-workflow/references/workflow-sprint-report.md new file mode 100644 index 0000000..b362796 --- /dev/null +++ b/skills/gitlink-workflow/references/workflow-sprint-report.md @@ -0,0 +1,549 @@ +# Workflow: Sprint Report(Sprint 报告) + +> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。 +> **AI Agent 工作流**:此工作流专为 AI Agent 设计,用于自动生成 Sprint 进度报告。 + +AI Agent 自动汇总 Sprint 期间的 Issue、PR、提交记录等数据,生成结构化的进度报告,帮助团队了解项目进展。 + +## 工作流概述 + +Sprint Report 工作流收集 Sprint 期间的所有活动数据,包括 Issue 完成情况、PR 合并状态、代码提交统计、团队成员贡献等,自动生成团队进度报告。 + +## 适用场景 + +- **Sprint 回顾**:为 Sprint 回顾会议提供数据支持 +- **进度汇报**:向管理层汇报项目进展 +- **团队协调**:协调团队工作计划和资源分配 +- **绩效评估**:评估团队和个人的工作效率 + +## 工作流步骤 + +### 步骤 1:确定报告时间范围 + +```bash +# 设置 Sprint 时间范围(通常为 2 周) +SPRINT_START="2026-01-01" +SPRINT_END="2026-01-14" + +# 或者基于当前时间计算 +SPRINT_END=$(date +%Y-%m-%d) +SPRINT_START=$(date -d "14 days ago" +%Y-%m-%d) +``` + +### 步骤 2:获取 Issue 统计 + +```bash +# 获取 Sprint 期间关闭的 Issue +CLOSED_ISSUES=$(gitlink-cli issue +list --state closed --format json | \ + jq '.data.issues[] | + select(.closed_at >= "'$SPRINT_START'" and .closed_at <= "'$SPRINT_END'")') + +# 获取新增 Issue +NEW_ISSUES=$(gitlink-cli issue +list --state open --format json | \ + jq '.data.issues[] | + select(.created_at >= "'$SPRINT_START'" and .created_at <= "'$SPRINT_END'")') + +# 统计 Issue 数据 +CLOSED_COUNT=$(echo "$CLOSED_ISSUES" | jq -s 'length') +NEW_COUNT=$(echo "$NEW_ISSUES" | jq -s 'length') +``` + +### 步骤 3:获取 PR 统计 + +```bash +# 获取 Sprint 期间合并的 PR +MERGED_PRS=$(gitlink-cli pr +list --state merged --format json | \ + jq '.data.prs[] | + select(.merged_at >= "'$SPRINT_START'" and .merged_at <= "'$SPRINT_END'")') + +# 获取新建的 PR +NEW_PRS=$(gitlink-cli pr +list --state open --format json | \ + jq '.data.prs[] | + select(.created_at >= "'$SPRINT_START'" and .created_at <= "'$SPRINT_END'")') + +# 统计 PR 数据 +MERGED_COUNT=$(echo "$MERGED_PRS" | jq -s 'length') +NEW_PR_COUNT=$(echo "$NEW_PRS" | jq -s 'length') +``` + +### 步骤 4:获取提交统计 + +```bash +# 获取项目活动数据 +ACTIVITY=$(gitlink-cli api GET /:owner/:repo/activity --format json | \ + jq ".data.activity[] | + select(.created_at >= \"$SPRINT_START\" and .created_at <= \"$SPRINT_END\")") + +# 提取提交数据 +COMMITS=$(echo "$ACTIVITY" | jq 'select(.type == "commit")') +COMMIT_COUNT=$(echo "$COMMITS" | jq -s 'length') +``` + +### 步骤 5:分析团队贡献 + +```bash +# 按团队成员统计贡献 +CONTRIBUTORS=$(gitlink-cli api GET /:owner/:repo/activity --format json | \ + jq ".data.activity[] | + select(.created_at >= \"$SPRINT_START\" and .created_at <= \"$SPRINT_END\") | + .author | + group_by(.) | + map({developer: .[0], count: length}) | + sort_by(.count) | reverse") +``` + +### 步骤 6:生成 Sprint 报告 + +```bash +# 生成结构化的 Sprint 报告 +SPRINT_REPORT="# 📊 Sprint 进度报告 + +**时间范围**: $SPRINT_START 至 $SPRINT_END +**Sprint 周期**: 14 天 + +## 🎯 目标达成情况 + +### Issue 统计 +- ✅ **完成 Issue**: $CLOSED_COUNT 个 +- 🆕 **新增 Issue**: $NEW_COUNT 个 +- 📈 **完成率**: $(($CLOSED_COUNT * 100 / ($CLOSED_COUNT + $NEW_COUNT)))% + +### Pull Request 统计 +- 🔀 **合并 PR**: $MERGED_COUNT 个 +- 🆕 **新建 PR**: $NEW_PR_COUNT 个 +- ✅ **合并率**: $(($MERGED_COUNT * 100 / ($MERGED_COUNT + $NEW_PR_COUNT)))% + +### 代码提交统计 +- 💻 **提交次数**: $COMMIT_COUNT 次 +- 📊 **日均提交**: $(($COMMIT_COUNT / 14)) 次/天 + +## 👥 团队贡献 +$(echo "$CONTRIBUTORS" | jq -r '.[] | "- **\(.developer)**: \(.count) 次贡献"') + +## 🎉 主要成就 +$(echo "$CLOSED_ISSUES" | jq -r '.[] | "- 完成 Issue: \(.subject)"') + +## 🔄 进行中工作 +$(echo "$NEW_ISSUES" | jq -r '.[] | "- 新建 Issue: \(.subject)"') + +## 📈 下期计划 +1. 继续进行中的 Issue 开发 +2. 新功能规划和设计 +3. 技术债务清理 +4. 性能优化工作" + +# 输出报告 +echo "$SPRINT_REPORT" +``` + +## 完整工作流示例 + +```bash +#!/bin/bash + +# Sprint 报告自动化生成脚本 + +OWNER="username" +REPO="myproject" +REPORT_DIR="sprint_reports" + +# 获取时间范围 +SPRINT_NUMBER=$1 +if [ -z "$SPRINT_NUMBER" ]; then + # 计算当前是第几个 Sprint(假设每 Sprint 2 周,从项目开始计算) + PROJECT_START="2026-01-01" + CURRENT_DATE=$(date +%Y-%m-%d) + DAYS_DIFF=$(( ($(date -d "$CURRENT_DATE" +%s) - $(date -d "$PROJECT_START" +%s)) / 86400 )) + SPRINT_NUMBER=$((DAYS_DIFF / 14 + 1)) +fi + +SPRINT_START=$(date -d "$((SPRINT_NUMBER - 1)) weeks ago" +%Y-%m-%d) +SPRINT_END=$(date -d "$((SPRINT_NUMBER - 1)) weeks ago +14 days" +%Y-%m-%d) + +echo "生成 Sprint $SPRINT_NUMBER 报告 ($SPRINT_START - $SPRINT_END)" + +# 创建报告目录 +mkdir -p "$REPORT_DIR" + +# 1. 获取 Issue 数据 +echo "收集 Issue 数据..." +ISSUE_DATA=$(gitlink-cli issue +list --owner $OWNER --repo $REPO --format json) + +CLOSED_ISSUES=$(echo "$ISSUE_DATA" | jq -r ".data.issues[] | + select(.closed_at >= \"$SPRINT_START\" and .closed_at <= \"$SPRINT_END\")") + +NEW_ISSUES=$(echo "$ISSUE_DATA" | jq -r ".data.issues[] | + select(.created_at >= \"$SPRINT_START\" and .created_at <= \"$SPRINT_END\")") + +CLOSED_COUNT=$(echo "$CLOSED_ISSUES" | jq -s 'length') +NEW_COUNT=$(echo "$NEW_ISSUES" | jq -s 'length') + +# 2. 获取 PR 数据 +echo "收集 PR 数据..." +PR_DATA=$(gitlink-cli pr +list --owner $OWNER --repo $REPO --format json) + +MERGED_PRS=$(echo "$PR_DATA" | jq -r ".data.prs[] | + select(.merged_at >= \"$SPRINT_START\" and .merged_at <= \"$SPRINT_END\")") + +NEW_PRS=$(echo "$PR_DATA" | jq -r ".data.prs[] | + select(.created_at >= \"$SPRINT_START\" and .created_at <= \"$SPRINT_END\")") + +MERGED_COUNT=$(echo "$MERGED_PRS" | jq -s 'length') +NEW_PR_COUNT=$(echo "$NEW_PRS" | jq -s 'length') + +# 3. 获取提交数据 +echo "收集提交数据..." +COMMITS=$(gitlink-cli api GET "/$OWNER/$REPO/commits" --format json | \ + jq -r ".data[] | + select(.committed_date >= \"$SPRINT_START\" and .committed_date <= \"$SPRINT_END\")") + +COMMIT_COUNT=$(echo "$COMMITS" | jq -s 'length') + +# 4. 分析团队贡献 +echo "分析团队贡献..." +CONTRIBUTORS=$(echo "$COMMITS" | jq -r '.author | group_by(.) | + map({developer: .[0], count: length}) | + sort_by(.count) | reverse') + +# 5. 分析 Issue 标签 +echo "分析 Issue 分类..." +FEATURES=$(echo "$CLOSED_ISSUES" | jq -r '[.[] | select(.issue_tags[]?.name == "feature")] | length') +BUGS=$(echo "$CLOSED_ISSUES" | jq -r '[.[] | select(.issue_tags[]?.name == "bug")] | length') +ENHANCEMENTS=$(echo "$CLOSED_ISSUES" | jq -r '[.[] | select(.issue_tags[]?.name == "enhancement")] | length') + +# 6. 计算完成率 +COMPLETION_RATE=0 +if [ $((CLOSED_COUNT + NEW_COUNT)) -gt 0 ]; then + COMPLETION_RATE=$((CLOSED_COUNT * 100 / (CLOSED_COUNT + NEW_COUNT))) +fi + +# 7. 生成报告 +echo "生成 Sprint 报告..." +REPORT_FILE="$REPORT_DIR/sprint_${SPRINT_NUMBER}_$(date +%Y%m%d).md" + +cat > "$REPORT_FILE" << EOF +# 📊 Sprint $SPRINT_NUMBER 进度报告 + +**时间范围**: $SPRINT_START 至 $SPRINT_END +**生成时间**: $(date +%Y-%m-%d) +**报告周期**: 14 天 + +## 🎯 Sprint 目标达成情况 + +### 总体概览 +| 指标 | 数量 | 说明 | +|------|------|------| +| ✅ 完成 Issue | $CLOSED_COUNT 个 | Sprint 期间关闭的 Issue | +| 🆕 新增 Issue | $NEW_COUNT 个 | Sprint 期间新建的 Issue | +| 🔀 合并 PR | $MERGED_COUNT 个 | Sprint 期间合并的 PR | +| 🆕 新建 PR | $NEW_PR_COUNT 个 | Sprint 期间新建的 PR | +| 💻 代码提交 | $COMMIT_COUNT 次 | Sprint 期间的提交次数 | + +### 完成率分析 +- **Issue 完成率**: ${COMPLETION_RATE}% +- **PR 合并率**: $((MERGED_COUNT * 100 / (MERGED_COUNT + NEW_PR_COUNT)))% +- **平均日提交**: $((COMMIT_COUNT / 14)) 次/天 + +## 📊 Issue 分类统计 + +| 分类 | 数量 | 占比 | +|------|------|------| +| 新功能 | $FEATURES 个 | $((FEATURES * 100 / CLOSED_COUNT))% | +| Bug 修复 | $BUGS 个 | $((BUGS * 100 / CLOSED_COUNT))% | +| 功能改进 | $ENHANCEMENTS 个 | $((ENHANCEMENTS * 100 / CLOSED_COUNT))% | + +## 👥 团队贡献统计 + +$(echo "$CONTRIBUTORS" | jq -r '.[] | | + "| **\(.developer)** | \(.count) 次提交 | $((.count * 100 / COMMIT_COUNT))% |"') + +## 🎉 主要成就 + +### 完成的 Issue +$(echo "$CLOSED_ISSUES" | jq -r '"- [\(.subject)](#issue/\(.id)) - \(.assigned_to // "未分配")"') + +### 合并的 PR +$(echo "$MERGED_PRS" | jq -r '"- [\(.title)](#pr/\(.id)) - \(.author.login)"') + +## 🔄 进行中的工作 + +### 未完成的 Issue +$(echo "$NEW_ISSUES" | jq -r '"- [\(.subject)](#issue/\(.id)) - \(.assigned_to // "未分配")"') + +### 待合并的 PR +$(echo "$NEW_PRS" | jq -r '"- [\(.title)](#pr/\(.id)) - \(.author.login)"') + +## 📈 趋势分析 + +### 代码活动趋势 +- 本 Sprint 共有 **$COMMIT_COUNT 次提交**,日均 **$((COMMIT_COUNT / 14)) 次** +- 比上 Sprint $([[ $SPRINT_NUMBER -gt 1 ]] && echo "增长了/减少了 XX%" || echo "为基线数据") + +### 团队效率分析 +- 团队成员积极参与,贡献分布较为均匀 +- 代码审查及时,PR 合并率良好 + +## ⚠️ 风险和问题 + +### 当前风险 +- 高优先级 Issue 积压:$(echo "$NEW_ISSUES" | jq '[.[] | select(.priority_id == 1)] | length') 个 +- 长期未解决的 Issue:$(echo "$NEW_ISSUES" | jq '[.[] | select(.created_at < "'$SPRINT_START'")] | length') 个 + +### 技术债务 +- 代码复用待改进 +- 测试覆盖率需要提升 +- 文档需要更新 + +## 📋 下期计划 + +### 主要目标 +1. 继续完成当前进行中的 Issue +2. 优化代码质量和测试覆盖 +3. 更新项目文档 +4. 技术债务清理 + +### 资源规划 +- 开发资源:保持当前团队配置 +- 时间规划:重点关注高优先级 Issue +- 技术重点:性能优化和代码重构 + +## 🙏 致谢 + +感谢所有团队成员在 Sprint $SPRINT_NUMBER 期间的辛勤工作! + +--- +**报告生成**: $(date +%Y-%m-%d %H:%M:%S) +**数据来源**: GitLink API +**报告类型**: 自动化 Sprint 报告 +EOF + +echo "✅ Sprint 报告已生成: $REPORT_FILE" + +# 8. 可选:创建 Issue 讨论报告 +echo "创建 Sprint 回顾 Issue..." +REVIEW_ISSUE_BODY="## Sprint $SPRINT_NUMBER 回顾 + +### Sprint 报告 +完整的 Sprint 报告请查看: [Sprint $SPRINT_NUMBER 报告](../../blob/master/$REPORT_FILE) + +### 讨论要点 +1. 目标达成情况分析 +2. 团队协作效果评估 +3. 流程改进建议 +4. 下 Sprint 目标规划 + +### 问题跟踪 +- 需要解决的问题 +- 改进建议 +- 风险识别" + +gitlink-cli issue +create \ + --owner $OWNER \ + --repo $REPO \ + --title "Sprint $SPRINT_NUMBER 回顾" \ + --body "$REVIEW_ISSUE_BODY" + +echo "Sprint 报告工作流完成!" +``` + +## AI Agent 集成示例 + +Claude Code 等 AI Agent 可以深度集成此工作流: + +```python +# AI Agent 生成 Sprint 报告 +def generate_sprint_report(owner, repo, sprint_number): + """AI Agent 自动生成 Sprint 进度报告""" + + # 1. 确定 Sprint 时间范围 + sprint_start, sprint_end = calculate_sprint_period(sprint_number) + + # 2. 收集数据 + sprint_data = collect_sprint_data(owner, repo, sprint_start, sprint_end) + + # 3. AI 分析数据 + analysis = analyze_sprint_performance(sprint_data) + + # 4. 生成报告 + report = generate_report_content(sprint_number, sprint_data, analysis) + + # 5. 保存报告并创建回顾 Issue + save_report(report, sprint_number) + create_review_issue(owner, repo, sprint_number, report) + + return report + +def collect_sprint_data(owner, repo, start_date, end_date): + """收集 Sprint 数据""" + + return { + 'issues': { + 'closed': get_closed_issues(owner, repo, start_date, end_date), + 'new': get_new_issues(owner, repo, start_date, end_date) + }, + 'pull_requests': { + 'merged': get_merged_prs(owner, repo, start_date, end_date), + 'new': get_new_prs(owner, repo, start_date, end_date) + }, + 'commits': get_commits(owner, repo, start_date, end_date), + 'contributors': get_contributor_stats(owner, repo, start_date, end_date) + } + +def analyze_sprint_performance(data): + """AI 分析 Sprint 表现""" + + analysis = { + 'velocity': calculate_velocity(data), + 'trends': identify_trends(data), + 'risks': identify_risks(data), + 'recommendations': generate_recommendations(data) + } + + # AI 分析完成率趋势 + completion_rate = len(data['issues']['closed']) / ( + len(data['issues']['closed']) + len(data['issues']['new']) + ) * 100 + + if completion_rate > 80: + analysis['performance'] = 'excellent' + elif completion_rate > 60: + analysis['performance'] = 'good' + else: + analysis['performance'] = 'needs_improvement' + + return analysis + +def generate_report_content(sprint_number, data, analysis): + """AI 生成报告内容""" + + report = f"""# 📊 Sprint {sprint_number} 进度报告 + +## 🎯 目标达成情况 + +### 总体概览 +- **完成 Issue**: {len(data['issues']['closed'])} 个 +- **新增 Issue**: {len(data['issues']['new'])} 个 +- **合并 PR**: {len(data['pull_requests']['merged'])} 个 +- **代码提交**: {len(data['commits'])} 次 + +### AI 分析结果 +- **表现评级**: {analysis['performance']} +- **团队速度**: {analysis['velocity']} story points +- **主要趋势**: {analysis['trends']} + +## 🎉 主要成就 +""" + + # 添加主要成就 + for issue in data['issues']['closed'][:5]: + report += f"- {issue['subject']} (#{issue['id']})\n" + + # 添加风险和建议 + report += "\n## ⚠️ 风险识别\n" + for risk in analysis['risks']: + report += f"- {risk}\n" + + report += "\n## 💡 改进建议\n" + for recommendation in analysis['recommendations']: + report += f"- {recommendation}\n" + + return report +``` + +## 报告模板 + +### 标准报告结构 + +```markdown +# Sprint {NUMBER} 进度报告 + +## 元信息 +- **时间范围**: {START_DATE} - {END_DATE} +- **Sprint 周期**: 14 天 +- **生成时间**: {TIMESTAMP} + +## 目标达成 +### 完成情况 +- 计划完成: X 个 Issue +- 实际完成: Y 个 Issue +- 完成率: Z% + +## 工作统计 +### Issue 统计 +- 关闭: N 个 +- 新建: M 个 +- 分类统计 + +### PR 统计 +- 合并: N 个 +- 新建: M 个 +- 合并率: X% + +### 提交统计 +- 总提交: N 次 +- 日均: X 次 + +## 团队贡献 +- 成员A: N 次贡献 +- 成员B: M 次贡献 + +## 风险和问题 +- 当前风险 +- 技术债务 +- 阻塞问题 + +## 下期计划 +- 主要目标 +- 资源规划 +- 时间安排 +``` + +## 数据分析维度 + +### 1. 速度分析 +- Story Points 完成 +- Issue 完成数量 +- PR 合并数量 + +### 2. 质量分析 +- Bug 修复比例 +- 代码审查通过率 +- 测试覆盖率变化 + +### 3. 效率分析 +- 平均 Issue 解决时间 +- 平均 PR 合并时间 +- 代码审查周期 + +### 4. 团队分析 +- 成员贡献分布 +- 协作效率 +- 沟通成本 + +## 最佳实践 + +1. **定期生成**:每个 Sprint 结束后及时生成报告 +2. **数据准确**:确保收集的数据完整准确 +3. **客观分析**:基于数据进行客观分析 +4. **行动导向**:报告应包含可执行的改进建议 +5. **团队参与**:让团队成员参与报告讨论 + +## 质量保证 + +报告质量检查: + +- [ ] 数据完整性检查 +- [ ] 计算准确性验证 +- [ ] 格式一致性检查 +- [ ] 语法和拼写检查 +- [ ] 链接有效性验证 +- [ ] 客观性审查 + +## References + +- [workflow-issue-triage](workflow-issue-triage.md) — Issue 分类工作流 +- [workflow-pr-review](workflow-pr-review.md) — PR 审查工作流 +- [gitlink-workflow](../SKILL.md) — 工作流总览 +- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数 +- [pm-sprint](../../gitlink-pm/references/pm-sprint.md) — Sprint 管理 +- [pm-report](../../gitlink-pm/references/pm-report.md) — 周报生成