feat: add multi-arch image publishing

This commit is contained in:
zhoujun0601
2026-08-13 11:28:33 -04:00
parent 4fa0a539fa
commit 618fc19bd7
12 changed files with 217 additions and 20 deletions
+1 -1
View File
@@ -43,7 +43,7 @@
| 方法与路径 | 鉴权 | 行为 |
| --- | --- | --- |
| `GET /api/v1/system/status` | 匿名 | `200 {initialized,version,appServer}`。当前版本字段为 `0.2.0`。 |
| `GET /api/v1/system/status` | 匿名 | `200 {initialized,version,appServer}`。`version` 为镜像构建时注入的应用版本,未注入时默认为 `0.2.0`。 |
| `POST /api/v1/setup` | 匿名、仅未初始化 | body `{username,password,timezone}`;用户名至少 3 位、密码至少 10 位,否则 400;时区有效时写入,否则使用默认 UTC。事务创建唯一管理员和通用设置,设置 session,返回 `201 {ok:true}`;已初始化返回 409。 |
| `POST /api/v1/auth/login` | 匿名 | body `{username,password}`;未初始化返回 409,错误凭据返回 401,成功设置 session 并返回 `200 {ok:true}`,限流返回 429。 |
| `任意方法 /api/v1/auth/me` | session;非 `GET`/`HEAD` 还需来源头 | `200 {username}`。前端使用 `GET`。 |
+1 -1
View File
@@ -32,7 +32,7 @@ func (a *App) api(w http.ResponseWriter, r *http.Request) {
}
}
a.mu.RUnlock()
jsonOut(w, 200, map[string]any{"initialized": a.store.Initialized(), "version": "0.2.0", "appServer": connected})
jsonOut(w, 200, map[string]any{"initialized": a.store.Initialized(), "version": Version, "appServer": connected})
return
}
if p == "setup" && r.Method == "POST" {
+3
View File
@@ -25,6 +25,9 @@ import (
webassets "codex-helper/internal/web"
)
// Version is overridden at build time for release images.
var Version = "0.2.0"
type App struct {
dataDir string
store *store.Store
+22
View File
@@ -23,6 +23,28 @@ func TestSystemStatusRejectsNonGETMethods(t *testing.T) {
}
}
func TestSystemStatusReturnsBuildVersion(t *testing.T) {
a := newReminderTestApp(t)
originalVersion := Version
Version = "1.2.3-test"
t.Cleanup(func() { Version = originalVersion })
recorder := httptest.NewRecorder()
request := httptest.NewRequest(http.MethodGet, "/api/v1/system/status", nil)
a.api(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, body = %s", recorder.Code, recorder.Body.String())
}
var body struct {
Version string `json:"version"`
}
if err := json.Unmarshal(recorder.Body.Bytes(), &body); err != nil {
t.Fatal(err)
}
if body.Version != "1.2.3-test" {
t.Fatalf("version = %q; want %q", body.Version, "1.2.3-test")
}
}
func TestDashboardSerializesNilListsAsEmptyArrays(t *testing.T) {
a := newReminderTestApp(t)
a.runtimes[1] = &accountRuntime{}