Gridea Pro 版本
main 分支 HEAD (b84db26)
操作系统
macOS (Apple Silicon)
系统版本
Darwin 25.4.0(问题与平台无关)
优先级
P1 (Netlify 部署正确性)
Bug 描述
backend/internal/deploy/netlify_deployer.go:100-119 的 Deploy 流程:
scanAndHashFiles 扫描本地文件。
createDeploy 拿到 deployId 和 required。
uploadFiles 并发 PUT 缺失文件。
直接 logger(\"✅ Netlify 部署成功!\") 返回。
问题 :上传完成只是"Netlify 收到了所有文件"的信号;实际进入 "Ready" 状态还要经过:
内部校验 / CDN 分发;
Build plugin 执行(即便是静态站,Netlify 也会跑一些内置 plugin);
DNS / SSL 同步;
遇到 build plugin 报错或 deploy 超限时会被置为 error 状态。
对于用户,state 可能还在 processing / uploading / enqueued,甚至最终变成 error。当前代码完全不 poll /api/v1/deploys/{id},用户 UI 永远看到"成功",打开站点却看到"Deploy failed"或旧版本。
此外 deployId 从 createDeploy 拿到之后从未使用 (除了传给 uploadFiles URL),说明原本就设计漏了 poll 这一步。
复现步骤
配置一个 Netlify 站点,故意在 _redirects 里写一条错误规则。
发布。
所有文件正常上传,应用弹"✅ 成功"。
打开 Netlify 后台:该 deploy 状态实际是 Deploy failed。
访问站点:依然是旧版本。
或更常见场景:
大站点上传完成后,Netlify 端还需 30s-2min 处理。
用户关闭应用准备休息。
Netlify 最终成功或失败,用户毫不知情。
期望行为
上传完成后 poll GET /api/v1/deploys/{id},直到 state ∈ {ready, error} 或达到超时(建议 5 分钟)。
轮询期间通过结构化事件通知前端"Netlify 正在处理中..."(参见 issue [Bug] 前端完全未监听 deploy-log 事件,部署过程无任何进度反馈 #43 的结构化事件设计)。
ready → 成功 toast。
error → 读取 error_message / title 字段在 UI 展示。
5 分钟仍未 ready → 显示"仍在处理中,请稍后到 Netlify 后台查看",但不要 把这种情况当成失败;建议提供一个按钮打开该 deploy URL。
实际行为
上传一完就宣布成功,用户无法知晓 Netlify 后续处理结果。
截图 / 日志
无。
补充信息 — 最佳解决方案
新增 pollDeployStatus 步骤
type netlifyDeployStatus struct {
Id string `json:\"id\"`
State string `json:\"state\"` // uploading / processing / ready / error
DeployUrl string `json:\"deploy_url\"`
ErrorMsg string `json:\"error_message\"`
DeployTime int `json:\"deploy_time\"`
}
func (p * NetlifyProvider ) pollDeployStatus (ctx context.Context , deployId , token string , logger LogFunc ) (* netlifyDeployStatus , error ) {
apiURL := fmt.Sprintf (\" % s / deploys / % s \" , netlifyAPIBase , deployId )
deadline := time .Now ().Add (5 * time .Minute )
interval := 2 * time .Second
for {
if time .Now ().After (deadline ) {
return nil , fmt.Errorf (\" 等待 Netlify 处理超时 ,最后状态未知 \" )
}
if err := ctx .Err (); err != nil {
return nil , err
}
req , _ := http .NewRequestWithContext (ctx , http .MethodGet , apiURL , nil )
req .Header .Set (\" Authorization \" , \"Bearer \"+ token )
resp , err := p .client .Do (req )
if err != nil {
// 短暂错误,继续 poll
logger (fmt.Sprintf (\" poll 失败 (将重试 ): % v \" , err ))
} else {
bodyBytes , _ := io .ReadAll (resp .Body )
resp .Body .Close ()
if resp .StatusCode == http .StatusOK {
var st netlifyDeployStatus
if json .Unmarshal (bodyBytes , & st ) == nil {
logger (fmt.Sprintf (\" 状态 : % s \" , st .State ))
switch st.State {
case \"ready \" :
return & st , nil
case \"error \" :
return & st , fmt.Errorf (\" Netlify 处理失败 : % s \" , st .ErrorMsg )
}
}
}
}
select {
case <- ctx .Done ():
return nil , ctx .Err ()
case <- time .After (interval ):
}
// 指数退避到 10s 上限
if interval < 10 * time .Second {
interval *= 2
}
}
}
Deploy 最后加:
logger (\" 文件上传完成 ,等待 Netlify 处理 ... \" )
status , err := p .pollDeployStatus (ctx , deployId , token , logger )
if err != nil {
return err
}
logger (fmt.Sprintf (\" ✅ Netlify 部署成功 : % s \" , status .DeployUrl ))
结合其他 issue
Vercel 侧对照
Vercel 也有类似问题,但更复杂(还有 checks / preview)。可以在本 issue 落地后单独开一个"Vercel deploy 状态轮询"的 follow-up。
单测
Mock Netlify API 返回 uploading→processing→ready,验证 Deploy 成功。
Mock 返回 error,验证返回错误并带 error_message。
ctx 取消中途,立即返回。
影响文件:
backend/internal/deploy/netlify_deployer.go
新增单测。
检查清单
Gridea Pro 版本
main 分支 HEAD (b84db26)
操作系统
macOS (Apple Silicon)
系统版本
Darwin 25.4.0(问题与平台无关)
优先级
P1(Netlify 部署正确性)
Bug 描述
backend/internal/deploy/netlify_deployer.go:100-119的Deploy流程:scanAndHashFiles扫描本地文件。createDeploy拿到deployId和required。uploadFiles并发 PUT 缺失文件。logger(\"✅ Netlify 部署成功!\")返回。问题:上传完成只是"Netlify 收到了所有文件"的信号;实际进入 "Ready" 状态还要经过:
error状态。对于用户,
state可能还在processing/uploading/enqueued,甚至最终变成error。当前代码完全不 poll/api/v1/deploys/{id},用户 UI 永远看到"成功",打开站点却看到"Deploy failed"或旧版本。此外
deployId从createDeploy拿到之后从未使用(除了传给 uploadFiles URL),说明原本就设计漏了 poll 这一步。复现步骤
_redirects里写一条错误规则。Deploy failed。或更常见场景:
期望行为
GET /api/v1/deploys/{id},直到state ∈ {ready, error}或达到超时(建议 5 分钟)。ready→ 成功 toast。error→ 读取error_message/title字段在 UI 展示。实际行为
上传一完就宣布成功,用户无法知晓 Netlify 后续处理结果。
截图 / 日志
无。
补充信息 — 最佳解决方案
新增 pollDeployStatus 步骤
Deploy最后加:结合其他 issue
emit(\"verify\", \"info\", state, pollCount, -1)。Vercel 侧对照
Vercel 也有类似问题,但更复杂(还有 checks / preview)。可以在本 issue 落地后单独开一个"Vercel deploy 状态轮询"的 follow-up。
单测
uploading→processing→ready,验证 Deploy 成功。error,验证返回错误并带 error_message。影响文件:
backend/internal/deploy/netlify_deployer.go检查清单