Gogs 通过 curl 发布 Release 并上传附件

作者 mcx 日期 2026-07-23
Gogs 通过 curl 发布 Release 并上传附件

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
2
3
4
5
6
7
curl -s -L -u "user:****" \
-c /tmp/gogs_cookies.txt \
"http://your-gogs:3000/owner/repo/releases/new" \
-o /tmp/releases_new.html

# 从 HTML 中提取 CSRF token
grep -o 'name="_csrf" value="[^"]*"' /tmp/releases_new.html | head -1

输出类似:

1
name="_csrf" value="abc123XYZ..."

第二步:上传附件

将文件 POST 到 /releases/attachments,带上 CSRF token。Gogs 返回一个 UUID。

1
2
3
4
5
6
curl -s -L -u "user:****" \
-b /tmp/gogs_cookies.txt -c /tmp/gogs_cookies.txt \
-X POST \
-F "_csrf=你的CSRF值" \
-F "file=@/path/to/your-file.zip" \
"http://your-gogs:3000/releases/attachments"

返回:

1
{"uuid":"bb4a0810-840e-4e24-add1-ae5c007356e6"}

第三步:创建 Release

重新获取一次 CSRF token(之前的可能已失效),然后 POST 到表单地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 重新获取 CSRF
curl -s -L -u "user:****" \
-c /tmp/gogs_cookies2.txt \
"http://your-gogs:3000/owner/repo/releases/new" \
-o /tmp/releases_new2.html

CSRF=$(grep -o 'name="_csrf" value="[^"]*"' /tmp/releases_new2.html | head -1 | sed 's/.*value="//' | sed 's/"//')

# 提交 Release
curl -s -u "user:****" \
-b /tmp/gogs_cookies2.txt -c /tmp/gogs_cookies2.txt \
-X POST \
-d "_csrf=$CSRF" \
-d "tag_name=v1.0.0" \
-d "tag_target=main" \
-d "title=v1.0.0" \
-d "content=Release description here" \
-d "files=bb4a0810-840e-4e24-add1-ae5c007356e6" \
"http://your-gogs:3000/owner/repo/releases/new"

成功时返回 HTTP 302 重定向到 Release 页面。


关键字段说明

字段 说明
_csrf 从 HTML 页面提取的 CSRF token
tag_name Tag 名称,如 v1.0.0
tag_target 目标分支名,通常是 mainmaster
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 要现取现用。