Go 语言的 GitCode / AtomGit API 客户端库,提供对 GitCode 平台几乎所有 REST API (/api/v5) 的类型安全访问。
- 认证 — Bearer Token / PRIVATE-TOKEN Header /
access_tokenQuery 三种鉴权 + OAuth 2.0 授权码流程 - 仓库 — 创建/更新/删除/Fork/归档/转让,组织仓库,文件 CRUD,Tree/Blob,Raw,文件&图片上传
- Issue — 仓库 Issue CRUD、评论、标签、里程碑、操作日志、关联 PR、时间线、订阅者、依赖关系;用户/组织/企业级 Issue 查询
- Pull Request — CRUD、合并、文件/提交/评论/审查、标签、审查人/测试人分配、操作日志、关联 Issue、Diff/Patch
- 分支 — 列表/创建/删除,保护分支规则,提交比较,提交历史
- Webhook — CRUD、测试推送,Push/TagPull/Issue/PullRequest/Note 事件解析
- 用户 — 当前用户/指定用户、SSH 公钥、邮箱、动态、Star 仓库、Namespace、关注/取关
- 组织 / 企业 — 组织信息/成员/关注者/公开成员/屏蔽用户,企业成员、企业 Issue/PR、Issue 扩展状态、企业标签
- 组织团队 — 团队 CRUD、成员管理、仓库关联
- 组织 Webhook — 组织级 Webhook CRUD
- 组织标签 — 组织级标签 CRUD
- 搜索 — 仓库 / Issue / 用户
- 协作者 — 仓库协作者 CRUD、权限查询
- Topics — 仓库主题管理
- Commit Status — 提交状态、合并状态 (CI/CD 集成)
- Deploy Keys — 部署密钥 CRUD
- Git References — Git 引用 CRUD
- Git Tags — 轻量/注释标签、Release 资产管理
- Reactions — Issue/评论/PR 表情回应
- Wiki — Wiki 页面 CRUD
- 通知 — 增强通知操作(标记已读、线程详情、仓库通知)
- 仓库邀请 — 接受/拒绝仓库邀请
- 模板 — Issue 模板、PR 合并模板、Gitignore/License/Label 模板
- Markdown — Markdown 渲染
- 仓库统计 — 参与度、代码频率、提交活动、Punch Card
- 仓库归档 — 下载仓库压缩包
- 仓库设置 — Push 配置、PR 设置、模块开关、审查规则、下载统计
- 类型友好 —
FlexInt/FlexString/NullableTime等 JSON 容错类型,适配 GitCode 返回值类型漂移
- Go ≥ 1.26(
go.mod已锁定) - 一个 GitCode 个人访问令牌(PAT)或 OAuth 应用凭据
go get github.com/yi-nology/gitcode_api@latest当前最新版本为 v0.2.0,完整版本历史见 releases。
package main
import (
"context"
"fmt"
"log"
gitcode "github.com/yi-nology/gitcode_api"
)
func main() {
client := gitcode.NewClient("your-gitcode-token")
ctx := context.Background()
user, err := client.GetCurrentUser(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("当前用户: %s (%s)\n", user.Name, user.Login)
repos, err := client.ListRepositories(ctx, gitcode.ListRepositoriesOptions{
ListOptions: gitcode.ListOptions{Page: 1, PerPage: 10},
})
if err != nil {
log.Fatal(err)
}
for _, r := range repos {
fmt.Printf("- %s\n", r.FullName)
}
}更完整的示例参见 examples/main.go。
访问 GitCode → 个人设置 → 私人令牌 创建 Token。
Client 默认使用 Authorization: Bearer <token>,可通过 SetAuthStyle 切换:
client := gitcode.NewClient("your-token") // Bearer (默认)
client.SetAuthStyle(gitcode.AuthStylePrivateToken) // PRIVATE-TOKEN Header
client.SetAuthStyle(gitcode.AuthStyleAccessToken) // access_token Query 参数client := gitcode.NewClientWithBaseURL("https://your-gitcode.com/api/v5", "token")
client.SetHTTPClient(&http.Client{Timeout: 60 * time.Second}) // 自定义超时默认 BaseURL 为 https://api.gitcode.com/api/v5,默认超时 30s。
适用于需要用户授权而非固定 Token 的场景:
oauth := gitcode.NewOAuthClient("client-id", "client-secret", "https://app.example.com/callback")
// 1. 引导用户跳转授权
url := oauth.AuthorizeURL("user_info projects", "random-state")
http.Redirect(w, r, url, http.StatusFound)
// 2. 用回调拿到的 code 换 token
token, err := oauth.ExchangeToken(ctx, code)
// 3. 用 token 创建 API 客户端
client := gitcode.NewClientFromOAuthToken(token)
// 4. 后续可用 refresh token 续期
token, err = oauth.RefreshToken(ctx, token.RefreshToken)下文示例中
ctx := context.Background(),owner/repo为仓库所有者和路径名。
// 创建仓库(私有)
private := false
repo, _ := client.CreateRepository(ctx, gitcode.CreateRepositoryOptions{
Name: "my-repo",
Description: "描述",
Private: &private,
AutoInit: &private, // true,初始化 README
})
// 更新 / 删除 / Fork
client.UpdateRepository(ctx, "owner", "my-repo", gitcode.UpdateRepositoryOptions{Description: "新描述"})
client.DeleteRepository(ctx, "owner", "my-repo")
client.ForkRepository(ctx, "owner", "repo", nil)
// 组织下创建仓库
client.CreateOrgRepository(ctx, "my-org", gitcode.CreateOrgRepoOptions{Name: "team-repo"})
// 文件 CRUD(content 需 base64 编码)
content, _ := client.GetRepositoryContent(ctx, "owner", "repo", "README.md", "main")
res, _ := client.CreateFile(ctx, "owner", "repo", "a.txt", gitcode.CreateFileOptions{
Message: "add a",
Content: base64.StdEncoding.EncodeToString([]byte("hi")),
Branch: "main",
})
client.UpdateFile(ctx, "owner", "repo", "a.txt", gitcode.UpdateFileOptions{
Message: "upd", Content: "...", SHA: res.Content.SHA, Branch: "main",
})
// 原始内容 / Tree / Blob / 贡献者 / 语言
raw, _ := client.GetRawFile(ctx, "owner", "repo", "README.md", "main")
tree, _ := client.GetTree(ctx, "owner", "repo", "main", true)
blob, _ := client.GetBlob(ctx, "owner", "repo", sha)
contribs, _ := client.ListContributors(ctx, "owner", "repo")
langs, _ := client.GetLanguages(ctx, "owner", "repo")
// 标签 / Release
tags, _ := client.ListTags(ctx, "owner", "repo")
release, _ := client.CreateRelease(ctx, "owner", "repo", gitcode.CreateReleaseOptions{
TagName: "v1.0.0", Title: "v1.0.0", Body: "release notes",
})
client.DeleteRelease(ctx, "owner", "repo", release.TagName)// 下载仓库压缩包
tarGz, _ := client.GetRepositoryArchive(ctx, "owner", "repo", "main.tar.gz")
zip, _ := client.GetRepositoryArchive(ctx, "owner", "repo", "main.zip")
// 仓库统计
participation, _ := client.GetRepoParticipation(ctx, "owner", "repo")
codeFreq, _ := client.GetRepoCodeFrequency(ctx, "owner", "repo")
commitActivity, _ := client.GetRepoCommitActivity(ctx, "owner", "repo")
punchCard, _ := client.GetRepoPunchCard(ctx, "owner", "repo")// 列出主题
topics, _ := client.ListRepositoryTopics(ctx, "owner", "repo")
// 更新主题
client.UpdateRepositoryTopics(ctx, "owner", "repo", []string{"golang", "api", "sdk"})
// 添加/删除单个主题
client.AddRepositoryTopic(ctx, "owner", "repo", "new-topic")
client.DeleteRepositoryTopic(ctx, "owner", "repo", "old-topic")// 列出协作者
collabs, _ := client.ListCollaborators(ctx, "owner", "repo", gitcode.ListOptions{})
// 添加协作者
client.AddCollaborator(ctx, "owner", "repo", "username", &gitcode.AddCollaboratorOptions{
Permission: "push", // pull, push, admin
})
// 检查是否为协作者
isCollab, _ := client.IsCollaborator(ctx, "owner", "repo", "username")
// 获取协作者权限
perm, _ := client.GetCollaboratorPermission(ctx, "owner", "repo", "username")
// 移除协作者
client.RemoveCollaborator(ctx, "owner", "repo", "username")// 列出部署密钥
keys, _ := client.ListDeployKeys(ctx, "owner", "repo", gitcode.ListOptions{})
// 创建部署密钥
readOnly := true
key, _ := client.CreateDeployKey(ctx, "owner", "repo", gitcode.CreateDeployKeyOptions{
Title: "deploy",
Key: "ssh-ed25519 AAAA...",
ReadOnly: &readOnly,
})
// 获取/删除
client.GetDeployKey(ctx, "owner", "repo", key.ID)
client.DeleteDeployKey(ctx, "owner", "repo", key.ID)// Issue CRUD
issue, _ := client.CreateIssue(ctx, "owner", "repo", gitcode.CreateIssueOptions{
Title: "Bug 报告",
Body: "问题描述",
Labels: []string{"bug"},
})
client.UpdateIssue(ctx, "owner", "repo", int(issue.Number), gitcode.UpdateIssueOptions{State: gitcode.IssueStateClosed})
client.ReopenIssue(ctx, "owner", "repo", int(issue.Number))
// 评论
client.CreateIssueComment(ctx, "owner", "repo", int(issue.Number), "+1")
client.ListIssueComments(ctx, "owner", "repo", int(issue.Number))
// 仓库标签
client.CreateIssueLabel(ctx, "owner", "repo", "bug", "#ee0701")
client.UpdateIssueLabel(ctx, "owner", "repo", "bug", gitcode.UpdateLabelOptions{Color: "#d73a4a"})
client.AddIssueLabels(ctx, "owner", "repo", int(issue.Number), []string{"bug"})
client.ReplaceIssueLabels(ctx, "owner", "repo", int(issue.Number), []string{"bug", "p0"})
// 里程碑
ms, _ := client.CreateMilestone(ctx, "owner", "repo", "v2.0", "下个版本")
client.ListMilestones(ctx, "owner", "repo")
client.UpdateMilestone(ctx, "owner", "repo", int(ms.ID), gitcode.UpdateMilestoneOptions{State: "closed"})
// 操作日志 / 关联 PR
logs, _ := client.GetIssueOperateLogs(ctx, "owner", "repo", int(issue.Number))
prs, _ := client.GetIssueLinkedPRs(ctx, "owner", "repo", int(issue.Number))
// 时间线事件
timeline, _ := client.ListIssueTimelineEvents(ctx, "owner", "repo", int(issue.Number), gitcode.ListOptions{})
// 订阅者
subscribers, _ := client.ListIssueSubscribers(ctx, "owner", "repo", int(issue.Number), gitcode.ListOptions{})
client.SubscribeToIssue(ctx, "owner", "repo", int(issue.Number), "username")
client.UnsubscribeFromIssue(ctx, "owner", "repo", int(issue.Number), "username")
// Issue 依赖关系
deps, _ := client.ListIssueDependencies(ctx, "owner", "repo", int(issue.Number), gitcode.ListOptions{})
client.CreateIssueDependency(ctx, "owner", "repo", int(issue.Number), 42) // 依赖 issue #42
client.DeleteIssueDependency(ctx, "owner", "repo", int(issue.Number), 42)
// 指派人
assignees, _ := client.ListRepoAssignees(ctx, "owner", "repo", gitcode.ListOptions{})
client.AddIssueAssignees(ctx, "owner", "repo", int(issue.Number), []string{"user1", "user2"})
client.RemoveIssueAssignees(ctx, "owner", "repo", int(issue.Number), []string{"user1"})// 添加表情
client.CreateIssueReaction(ctx, "owner", "repo", int(issue.Number), gitcode.ReactionHeart)
client.CreateIssueReaction(ctx, "owner", "repo", int(issue.Number), gitcode.ReactionPlusOne)
// 列出表情
reactions, _ := client.ListIssueReactions(ctx, "owner", "repo", int(issue.Number), gitcode.ListOptions{})
// 删除表情
client.DeleteIssueReaction(ctx, "owner", "repo", int(issue.Number), reactions[0].ID)
// 评论表情
client.CreateIssueCommentReaction(ctx, "owner", "repo", commentID, gitcode.ReactionRocket)
client.ListIssueCommentReactions(ctx, "owner", "repo", commentID, gitcode.ListOptions{})pr, _ := client.CreatePullRequest(ctx, "owner", "repo", gitcode.CreatePullRequestOptions{
Title: "feat: xxx", Head: "feature", Base: "main",
})
// 合并 (Squash)
client.MergePullRequest(ctx, "owner", "repo", pr.Number, &gitcode.MergePullRequestOptions{
CommitMessage: "merge feat",
Squash: true,
})
// 文件 / 提交 / 评论 / 审查
client.ListPullRequestFiles(ctx, "owner", "repo", pr.Number)
client.ListPullRequestCommits(ctx, "owner", "repo", pr.Number)
client.CreatePullRequestReview(ctx, "owner", "repo", pr.Number, "LGTM", "APPROVE")
// 标签 / 审查人 / 测试人
client.AddPullRequestLabels(ctx, "owner", "repo", pr.Number, []string{"review"})
client.AssignPullRequestReviewers(ctx, "owner", "repo", pr.Number, "user1,user2")
client.AssignPullRequestTesters(ctx, "owner", "repo", pr.Number, "qa1")
client.HandlePullRequestReview(ctx, "owner", "repo", pr.Number, false) // force=false
// 关联 Issue / 操作日志
issues, _ := client.GetPullRequestLinkedIssues(ctx, "owner", "repo", pr.Number, gitcode.ListOptions{})
logs, _ := client.GetPullRequestOperateLogs(ctx, "owner", "repo", pr.Number)
// Diff / Patch
diff, _ := client.GetPullRequestDiff(ctx, "owner", "repo", pr.Number)
patch, _ := client.GetPullRequestPatch(ctx, "owner", "repo", pr.Number)
// 审查人管理
reviewers, _ := client.ListPullRequestReviewers(ctx, "owner", "repo", pr.Number)
client.RequestPullRequestReviewers(ctx, "owner", "repo", pr.Number, gitcode.PullRequestReviewRequest{
Reviewers: []string{"reviewer1", "reviewer2"},
})
// 审查操作
review, _ := client.GetPullRequestReview(ctx, "owner", "repo", pr.Number, reviewID)
client.SubmitPullRequestReview(ctx, "owner", "repo", pr.Number, reviewID, "LGTM", "APPROVE")
client.DismissPullRequestReview(ctx, "owner", "repo", pr.Number, reviewID, "Dismissed")
// PR 表情回应
client.CreatePullRequestCommentReaction(ctx, "owner", "repo", commentID, gitcode.ReactionHooray)// 创建提交状态
client.CreateCommitStatus(ctx, "owner", "repo", sha, gitcode.CreateCommitStatusOptions{
State: "success", // pending, success, error, failure
TargetURL: "https://ci.example.com/build/123",
Description: "Build passed",
Context: "ci/build",
})
// 列出提交状态
statuses, _ := client.ListCommitStatuses(ctx, "owner", "repo", sha, gitcode.ListOptions{})
// 获取合并状态(CI 整体状态)
combined, _ := client.GetCombinedStatus(ctx, "owner", "repo", sha)
fmt.Printf("总状态: %d 个检查\n", combined.TotalCount)// 创建提交评论
comment, _ := client.CreateCommitComment(ctx, "owner", "repo", sha, gitcode.CreateCommitCommentOptions{
Body: "Nice work!",
Path: "main.go",
Position: 10,
})
// 列出/获取/更新/删除
client.ListCommitComments(ctx, "owner", "repo", sha, gitcode.ListOptions{})
client.GetCommitComment(ctx, "owner", "repo", comment.ID)
client.UpdateCommitComment(ctx, "owner", "repo", comment.ID, gitcode.UpdateCommitCommentOptions{Body: "Updated"})
client.DeleteCommitComment(ctx, "owner", "repo", comment.ID)
// 列出仓库所有提交评论
client.ListRepoCommitComments(ctx, "owner", "repo", gitcode.ListOptions{})client.CreateBranch(ctx, "owner", "repo", gitcode.CreateBranchOptions{
BranchName: "dev", Refs: "main",
})
client.DeleteBranch(ctx, "owner", "repo", "dev")
// 保护分支规则
client.CreateBranchProtection(ctx, "owner", "repo", gitcode.CreateBranchProtectionOptions{
Name: "main",
RequiredApprovingReviews: 2,
AllowForcePushes: false,
})
client.ListBranchProtections(ctx, "owner", "repo")
client.DeleteBranchProtection(ctx, "owner", "repo", "main")
// 提交
commits, _ := client.ListCommits(ctx, "owner", "repo", gitcode.ListCommitsOptions{Branch: "main"})
commit, _ := client.GetCommit(ctx, "owner", "repo", commits[0].SHA)
cmp, _ := client.CompareCommits(ctx, "owner", "repo", "main", "dev")
fmt.Printf("ahead=%d behind=%d\n", cmp.AheadBy, cmp.BehindBy)// 列出引用
refs, _ := client.ListGitReferences(ctx, "owner", "repo", gitcode.ListOptions{})
// 列出分支引用
heads, _ := client.ListGitRefSubPaths(ctx, "owner", "repo", "heads/")
// 获取引用
ref, _ := client.GetGitReference(ctx, "owner", "repo", "heads/main")
// 创建引用
client.CreateGitReference(ctx, "owner", "repo", gitcode.CreateReferenceOptions{
Ref: "refs/heads/new-branch",
SHA: "abc123...",
})
// 更新引用
client.UpdateGitReference(ctx, "owner", "repo", "heads/main", gitcode.UpdateReferenceOptions{
SHA: "def456...",
Force: false,
})
// 删除引用
client.DeleteGitReference(ctx, "owner", "repo", "heads/old-branch")// 创建注释标签
annotatedTag, _ := client.CreateAnnotatedTag(ctx, "owner", "repo", gitcode.CreateAnnotatedTagOptions{
Tag: "v2.0.0",
Message: "Release v2.0.0",
Object: "abc123...",
Type: "commit",
})
// 获取注释标签
client.GetAnnotatedTag(ctx, "owner", "repo", annotatedTag.SHA)
// Release 资产
assets, _ := client.ListReleaseAssets(ctx, "owner", "repo", releaseID, gitcode.ListOptions{})
client.GetReleaseAsset(ctx, "owner", "repo", assetID)
client.DeleteReleaseAsset(ctx, "owner", "repo", assetID)
// 通过标签获取 Release
release, _ := client.GetReleaseByTag(ctx, "owner", "repo", "v1.0.0")
// 更新 Release
client.UpdateRelease(ctx, "owner", "repo", releaseID, gitcode.UpdateReleaseOptions{
Body: "Updated release notes",
})active := true
hook, _ := client.CreateWebhook(ctx, "owner", "repo", gitcode.CreateWebhookOptions{
URL: "https://example.com/hook",
Secret: "s3cret",
Events: []string{"push", "pull_request"},
Active: &active,
})
client.TestWebhook(ctx, "owner", "repo", hook.ID)
client.DeleteWebhook(ctx, "owner", "repo", hook.ID)接收并解析事件(以 Gin 为例):
payload, _ := io.ReadAll(r.Body)
switch r.Header.Get("X-Gitcode-Event") {
case "push":
e, _ := client.ParsePushEvent(payload)
log.Printf("push %s -> %s", e.Before[:8], e.After[:8])
case "pull_request":
e, _ := client.ParsePullRequestEvent(payload)
log.Printf("PR #%d %s", e.Number, e.Action)
case "issues":
e, _ := client.ParseIssueEvent(payload)
log.Printf("issue #%d %s", int(e.Issue.Number), e.Action)
case "note":
e, _ := client.ParseNoteEvent(payload)
log.Printf("note on %s", e.NoteType)
case "tag_push":
e, _ := client.ParseTagPushEvent(payload)
log.Printf("tag %s", e.Ref)
}还提供了
PushEvent/PullRequestWebhookEvent/IssueWebhookEvent/NoteWebhookEvent/TagPushEvent五种事件类型,见webhooks.go。
me, _ := client.GetCurrentUser(ctx)
user, _ := client.GetUser(ctx, "somebody")
emails, _ := client.ListEmails(ctx)
key, _ := client.CreateSSHKey(ctx, gitcode.CreateSSHKeyOptions{
Title: "mbp", Key: "ssh-ed25519 AAAA...",
})
client.ListSSHKeys(ctx, gitcode.ListOptions{PerPage: 50})
client.DeleteSSHKey(ctx, key.ID)
events, _ := client.GetUserEvents(ctx, me.Login, "2025", "") // 年度动态
starred, _ := client.ListStarredRepositories(ctx, gitcode.ListStarredReposOptions{})
ns, _ := client.GetNamespace(ctx, "somepath")// 列出关注者/被关注者
followers, _ := client.ListUserFollowers(ctx, "username", gitcode.ListOptions{})
following, _ := client.ListUserFollowing(ctx, "username", gitcode.ListOptions{})
// 当前用户的关注关系
myFollowers, _ := client.ListCurrentUserFollowers(ctx, gitcode.ListOptions{})
myFollowing, _ := client.ListCurrentUserFollowing(ctx, gitcode.ListOptions{})
// 关注/取关
client.FollowUser(ctx, "target-user")
client.UnfollowUser(ctx, "target-user")
// 检查是否关注
isFollowing, _ := client.IsFollowing(ctx, "target-user")// 组织
client.ListUserOrganizations(ctx, "username", gitcode.ListOptions{})
org, _ := client.GetOrgInfo(ctx, "my-org")
client.UpdateOrganization(ctx, "my-org", gitcode.UpdateOrgOptions{Description: "..."})
client.InviteOrgMember(ctx, "my-org", "newbie", gitcode.InviteMemberOptions{Permission: "write"})
client.RemoveOrgMember(ctx, "my-org", "newbie")
client.ListOrgMembers(ctx, "my-org", "admin", gitcode.ListOptions{})
// 企业
client.ListEnterpriseMembers(ctx, "my-ent", "", gitcode.ListOptions{})
client.UpdateEnterpriseMember(ctx, "my-ent", "user", gitcode.UpdateEnterpriseMemberOptions{Role: "admin"})
// 企业 Issue / PR
client.ListEnterpriseIssues(ctx, "my-ent", gitcode.ListUserIssuesOptions{State: "open"})
client.ListEnterprisePullRequests(ctx, "my-ent", gitcode.ListEnterprisePRsOptions{State: "open"})
client.ListEnterpriseLabels(ctx, "my-ent")
client.GetOrgIssueExtendSettings(ctx, "my-org") // 自定义状态扩展// 公开成员
publicMembers, _ := client.ListOrgPublicMembers(ctx, "my-org", gitcode.ListOptions{})
client.PublicizeOrgMembership(ctx, "my-org", "username")
client.ConcealOrgMembership(ctx, "my-org", "username")
isPublic, _ := client.IsOrgPublicMember(ctx, "my-org", "username")
// 屏蔽用户
blocked, _ := client.ListOrgBlockedUsers(ctx, "my-org", gitcode.ListOptions{})
client.BlockOrgUser(ctx, "my-org", "spammer")
client.UnblockOrgUser(ctx, "my-org", "spammer")
isBlocked, _ := client.IsOrgBlockedUser(ctx, "my-org", "spammer")// 创建团队
team, _ := client.CreateTeam(ctx, "my-org", gitcode.CreateTeamOptions{
Name: "backend",
Permission: "write",
Privacy: "closed",
})
// 列出/获取/更新/删除团队
teams, _ := client.ListOrgTeams(ctx, "my-org", gitcode.ListOptions{})
client.GetTeam(ctx, team.ID)
client.UpdateTeam(ctx, team.ID, gitcode.UpdateTeamOptions{Name: "backend-team"})
client.DeleteTeam(ctx, team.ID)
// 团队成员管理
client.ListTeamMembers(ctx, team.ID, gitcode.ListOptions{})
client.AddTeamMember(ctx, team.ID, "new-member")
client.RemoveTeamMember(ctx, team.ID, "old-member")
// 团队仓库管理
client.ListTeamRepositories(ctx, team.ID, gitcode.ListOptions{})
client.AddTeamRepository(ctx, team.ID, "my-org", "my-repo")
client.RemoveTeamRepository(ctx, team.ID, "my-org", "my-repo")// 创建组织 Webhook
active := true
hook, _ := client.CreateOrgWebhook(ctx, "my-org", gitcode.CreateOrgWebhookOptions{
URL: "https://example.com/org-hook",
Events: []string{"push", "repository"},
Active: &active,
})
// 列出/获取/更新/删除
hooks, _ := client.ListOrgWebhooks(ctx, "my-org", gitcode.ListOptions{})
client.GetOrgWebhook(ctx, "my-org", hook.ID)
client.UpdateOrgWebhook(ctx, "my-org", hook.ID, gitcode.UpdateOrgWebhookOptions{URL: "https://new-url.com"})
client.DeleteOrgWebhook(ctx, "my-org", hook.ID)// 创建组织标签
label, _ := client.CreateOrgLabel(ctx, "my-org", gitcode.CreateOrgLabelOptions{
Name: "priority:high",
Color: "#ff0000",
})
// 列出/获取/更新/删除
labels, _ := client.ListOrgLabels(ctx, "my-org", gitcode.ListOptions{})
client.GetOrgLabel(ctx, "my-org", label.ID)
client.UpdateOrgLabel(ctx, "my-org", label.ID, gitcode.UpdateOrgLabelOptions{Color: "#cc0000"})
client.DeleteOrgLabel(ctx, "my-org", label.ID)repos, _ := client.SearchRepositories(ctx, gitcode.SearchRepositoriesOptions{
Query: "gin web", Sort: "stars_count",
})
issues, _ := client.SearchIssues(ctx, gitcode.SearchIssuesOptions{
Query: "memory leak", Repo: "owner/repo", State: "open",
})
users, _ := client.SearchUsers(ctx, gitcode.SearchUsersOptions{Query: "octocat"})client.StarRepository(ctx, "owner", "repo")
starred, _ := client.IsRepositoryStarred(ctx, "owner", "repo") // bool
client.UnstarRepository(ctx, "owner", "repo")
stargazers, _ := client.ListStargazers(ctx, "owner", "repo", gitcode.ListOptions{})
watchers, _ := client.ListWatchers(ctx, "owner", "repo", gitcode.ListOptions{})// 列出通知(带筛选)
notifs, _ := client.ListNotificationsWithOptions(ctx, gitcode.ListNotificationsOptions{
ListOptions: gitcode.ListOptions{PerPage: 50},
Status: "unread",
})
// 获取通知线程详情
thread, _ := client.GetNotificationThread(ctx, threadID)
// 标记单个线程已读
client.MarkNotificationThreadAsRead(ctx, threadID)
// 标记所有通知已读
client.MarkNotificationsAsRead(ctx, gitcode.MarkNotificationsOptions{All: true})
// 仓库通知
repoNotifs, _ := client.ListRepoNotifications(ctx, "owner", "repo", gitcode.ListNotificationsOptions{})
client.MarkRepoNotificationsAsRead(ctx, "owner", "repo", gitcode.MarkNotificationsOptions{All: true})// 列出 Wiki 页面
pages, _ := client.ListWikiPages(ctx, "owner", "repo", gitcode.ListOptions{})
// 获取单个页面
page, _ := client.GetWikiPage(ctx, "owner", "repo", "Home")
// 创建页面
content := base64.StdEncoding.EncodeToString([]byte("# Hello Wiki"))
client.CreateWikiPage(ctx, "owner", "repo", gitcode.CreateWikiPageOptions{
Title: "New Page",
ContentBase64: content,
Message: "Create new page",
})
// 更新/删除
client.UpdateWikiPage(ctx, "owner", "repo", "New-Page", gitcode.UpdateWikiPageOptions{
ContentBase64: content,
Message: "Update page",
})
client.DeleteWikiPage(ctx, "owner", "repo", "Old-Page")// 列出待处理邀请
invitations, _ := client.ListPendingRepoInvitations(ctx, gitcode.ListOptions{})
// 接受/拒绝邀请
client.AcceptRepoInvitation(ctx, invitationID)
client.DeclineRepoInvitation(ctx, invitationID)// Issue 模板
issueTemplates, _ := client.ListIssueTemplates(ctx, "owner", "repo")
client.GetIssueTemplate(ctx, "owner", "repo", "bug_report")
// PR 合并模板
mergeTemplates, _ := client.ListPullRequestMergeTemplates(ctx, "owner", "repo")
// Gitignore 模板
gitignoreTemplates, _ := client.ListGitignoreTemplates(ctx)
client.GetGitignoreTemplate(ctx, "Go")
// License 模板
licenses, _ := client.ListLicenseTemplates(ctx)
client.GetLicenseTemplate(ctx, "mit")
// Label 模板
labelTemplates, _ := client.ListLabelTemplates(ctx)
client.GetLabelTemplate(ctx, "default")html, _ := client.RenderMarkdown(ctx, "**bold** and *italic*", "gfm", "owner/repo")
html, _ = client.RenderMarkdownRaw(ctx, "# Raw Markdown")client.UpdateRepoSettings(ctx, "owner", "repo", &gitcode.RepoSettings{HasIssues: true})
client.UpdatePushConfig(ctx, "owner", "repo", &gitcode.PushConfig{MaxFileSize: 104857600})
client.UpdatePRSettings(ctx, "owner", "repo", &gitcode.PRSettings{DefaultMergeMethod: "merge"})
client.SetModuleSetting(ctx, "owner", "repo", gitcode.ModuleSetting{Wiki: false})
client.UpdateReviewerConfig(ctx, "owner", "repo", gitcode.ReviewerConfig{MinApprovingReviews: 1})
// 归档 / 转让
client.ArchiveRepository(ctx, "owner", "repo")
client.TransferRepository(ctx, "owner", "repo", gitcode.TransferRepoOptions{NewOwner: "new-owner"})
// 限流
rl, _ := client.GetRateLimit(ctx)types.go 中定义了若干容错类型,用于处理 GitCode API 返回值类型不稳定的情况:
| 类型 | 用途 |
|---|---|
FlexInt |
同一字段可能是 123 或 "123" |
FlexString |
同一字段可能是 "abc" 或 123 |
NullableTime |
时间字段可能为空字符串 |
Timestamp |
字符串格式时间(RFC3339) |
Error |
API 错误响应结构(见下) |
Client 在 HTTP 状态码 ≥ 400 时返回标准 error(fmt.Errorf),错误信息包含方法、路径、状态码和响应体:
_, err := client.GetRepository(ctx, "owner", "missing")
if err != nil {
log.Println(err)
// 输出形如: GitCode API GET /repos/owner/missing returned 404: {"message":"404 Not Found"}
}如需进一步解析错误体,可使用 types.Error:
var apiErr gitcode.Error
if json.Unmarshal([]byte(extractBody(err)), &apiErr) == nil {
log.Printf("message=%s", apiErr.Message)
}gitcode_api/
├── client.go # Client 构造、鉴权、HTTP 请求、User、ListOptions、RateLimit
├── oauth.go # OAuthClient 授权码流程
├── repos.go # 仓库 / 文件 / Tree / Blob / 标签 / Release / 设置 / 归档 / 转让
├── repos_collaborators.go # 仓库协作者 CRUD、权限查询
├── repos_topics.go # 仓库主题管理
├── repos_statuses.go # 提交状态、合并状态 (CI/CD)
├── repos_deploy_keys.go # 部署密钥 CRUD
├── repos_reactions.go # Issue / 评论 / PR 表情回应
├── repos_wiki.go # Wiki 页面 CRUD
├── repos_invitations.go # 仓库邀请
├── repos_templates.go # Issue / PR 模板
├── repos_commits_comments.go # 提交评论
├── repos_archive.go # 仓库归档下载、统计
├── repos_assignees.go # 指派人管理
├── repos_reviewers.go # PR 审查人、Diff、Patch
├── repos_issues_timeline.go # Issue 时间线、订阅者、依赖关系
├── issues.go # Issue CRUD / 评论 / 标签 / 里程碑
├── enterprise_issues.go # 用户 / 组织 / 企业级 Issue、操作日志、关联 PR
├── pulls.go # Pull Request 全套 + 审查 / 测试 / 标签 / 企业 PR
├── branches.go # 分支 / 保护分支 / 提交 / 比较
├── webhooks.go # Webhook CRUD + 5 类事件解析
├── search.go # 搜索仓库 / Issue / 用户
├── users.go # SSH 公钥 / 邮箱 / 动态 / Star / Namespace
├── user_followers.go # 用户关注 / 取关
├── orgs.go # 组织 / 企业成员管理 / Issue 扩展配置
├── org_teams.go # 组织团队 CRUD / 成员 / 仓库
├── org_hooks.go # 组织 Webhook CRUD
├── org_labels.go # 组织标签 CRUD
├── org_members_enhanced.go # 公开成员 / 屏蔽用户 / 创建删除组织
├── milestones.go # 里程碑(带选项版本)
├── labels.go # 仓库标签更新 / 替换 / 企业标签
├── git_refs.go # Git 引用 CRUD
├── git_tags.go # 注释标签 / Release 资产
├── notifications_enhanced.go # 增强通知操作
├── misc.go # Gitignore/License/Label 模板 / Markdown / 用户仓库
├── types.go # FlexInt/FlexString/NullableTime/Error 等通用类型 + Star/通知 API
├── gitcode_test.go # 单元测试 + 真实 API 集成测试
└── examples/
└── main.go # 可运行的使用示例
本库覆盖了 GitCode API 的绝大部分功能,包括但不限于:
| 模块 | API 数量 | 状态 |
|---|---|---|
| 认证 & 用户 | 15+ | ✅ 完整 |
| 仓库 CRUD & 文件 | 30+ | ✅ 完整 |
| Issue / 标签 / 里程碑 | 25+ | ✅ 完整 |
| Pull Request | 30+ | ✅ 完整 |
| 分支 & 提交 | 15+ | ✅ 完整 |
| Webhook | 5 CRUD + 5 解析 | ✅ 完整 |
| 组织 / 企业 | 20+ | ✅ 完整 |
| 组织团队 | 12 | ✅ 完整 |
| 搜索 | 3 | ✅ 完整 |
| 协作者 | 5 | ✅ 完整 |
| Topics | 4 | ✅ 完整 |
| Commit Status | 3 | ✅ 完整 |
| Deploy Keys | 4 | ✅ 完整 |
| Git References | 6 | ✅ 完整 |
| Reactions | 12 | ✅ 完整 |
| Wiki | 5 | ✅ 完整 |
| 通知 | 6 | ✅ 完整 |
| 模板 | 7 | ✅ 完整 |
| 总计 | 200+ | ✅ |
测试分为两类:纯函数测试(不需要网络)和 真实 API 集成测试(会在你的账户下创建/删除临时仓库)。
# 默认运行(需在 gitcode_test.go 顶部填入有效 Token)
GITCODE_TOKEN="your-token" go test -v ./...
# 跳过需要联网的集成测试
go test -short ./...集成测试会真实创建仓库(
test-api-<timestamp>),测试结束后自动清理。请使用测试账号的 Token。
本项目参考了 gitcode-cli 的设计理念,提供 Go 语言的 API 客户端实现:
gitcode-cli (gc) |
gitcode_api |
|---|---|
gc auth login |
NewClient(token) / OAuthClient |
gc repo list |
ListRepositories() |
gc issue create |
CreateIssue() |
gc pr create |
CreatePullRequest() |
- gitcode-cli — GitCode 官方 CLI 工具
- git-platform-sdk — 多平台 Git SDK 统一接口(GitHub/GitLab/Gitea/Forgejo/GitCode)
MIT。