Gogs 是轻量级的自托管 Git 服务,但其 API 对 Release 的支持并不完整。本文记录如何通过 curl + web 表单完成 Release 创建和附件上传。
为什么不用 API
Gogs 的 API 端点 POST /api/v1/repos/{owner}/{repo}/releases 在部分版本中返回 404,无法通过 API 创建 Release。但 web 表单是可用的,所以绕道走表单提交。
验证方式:
1 | curl -s -u "user:pass" "http://your-gogs:3000/api/v1/repos/owner/repo/releases" |
如果返回 [] 说明 GET 可用,但 POST 可能返回 HTML 404 页面,此时只能走 web 表单。
完整流程
分三步:获取 CSRF token、上传附件、创建 Release。
第一步:获取 CSRF token
Gogs 的表单需要 CSRF token 和 session cookie 配合使用。
1 | curl -s -L -u "user:****" \ |
输出类似:
1 | name="_csrf" value="abc123XYZ..." |
第二步:上传附件
将文件 POST 到 /releases/attachments,带上 CSRF token。Gogs 返回一个 UUID。
1 | curl -s -L -u "user:****" \ |
返回:
1 | {"uuid":"bb4a0810-840e-4e24-add1-ae5c007356e6"} |
第三步:创建 Release
重新获取一次 CSRF token(之前的可能已失效),然后 POST 到表单地址。
1 | # 重新获取 CSRF |
成功时返回 HTTP 302 重定向到 Release 页面。
关键字段说明
| 字段 | 说明 |
|---|---|
_csrf |
从 HTML 页面提取的 CSRF token |
tag_name |
Tag 名称,如 v1.0.0 |
tag_target |
目标分支名,通常是 main 或 master |
title |
Release 标题 |
content |
Release 描述,支持 Markdown |
files |
附件 UUID,多个用逗号分隔 |
踩坑记录
1. 分支名不是 master
Gogs 默认分支可能是 main 而非 master。用错会报 “Target branch does not exist”。查看仓库首页确认:
1 | curl -s -u "user:****" "http://your-gogs:3000/owner/repo" | grep "Branch:" |
2. CSRF token 需要重新获取
上传附件后,原来的 CSRF token 可能失效。创建 Release 前需要重新访问 releases/new 页面获取新的 token。
3. 文件大小限制
Gogs 默认最大上传 32MB(可在 custom/conf/app.conf 中修改 [attachment] MAX_SIZE)。
4. cookie 文件要带对
上传附件和创建 Release 都需要带 session cookie(-b 和 -c 参数),否则 Gogs 不认 CSRF token。
验证
创建完成后,访问 Release 页面确认:
1 | http://your-gogs:3000/owner/repo/releases |
附件下载地址格式:
1 | http://your-gogs:3000/attachments/{uuid} |
总结
Gogs 的 Release API 不完整,但 web 表单是可靠的替代方案。核心流程就是三步:拿 CSRF、传附件、提交表单。记住每次都要带 cookie,CSRF 要现取现用。