mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
v1.26.27 could not start:
RegisterTaskFatal() [F] Unable to register cron task fail_unsatisfiable_jobs
Error: translation is missing for task "fail_unsatisfiable_jobs",
please add translation for "admin.dashboard.fail_unsatisfiable_jobs"
Received signal 15; terminating.
RegisterTaskFatal is fatal by design, so ONE absent locale key aborts the whole
server — there is no degraded mode. git.hanzo.ai served 503 from the moment CD
applied v1.26.27 until it was rolled back to v1.26.26, which also stops every
native .hanzo/workflows CI run, since this host is canonical and GitHub is only
the mirror.
Of the six tasks in tasks_actions.go this was the only one missing a key; the
phrasing matches its siblings ("Cancel actions abandoned jobs", "Stop actions
zombie tasks").
The test scans every tasks*.go for RegisterTaskFatal and asserts a matching
admin.dashboard.* key exists — 30 tasks covered today. Verified it fails when the
key is removed and passes when restored, so it genuinely guards the regression
rather than just passing.
Co-authored-by: Hanzo Dev <[email protected]>
55 lines
1.6 KiB
Go
55 lines
1.6 KiB
Go
package cron
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"testing"
|
|
)
|
|
|
|
// RegisterTaskFatal aborts the whole server when a task has no
|
|
// "admin.dashboard.<task>" translation — a missing i18n key is therefore a full
|
|
// outage, not a cosmetic gap. v1.26.27 shipped without
|
|
// admin.dashboard.fail_unsatisfiable_jobs and git.hanzo.ai served 503 until it
|
|
// was rolled back. This keeps that from shipping again.
|
|
func TestEveryRegisteredCronTaskHasATranslation(t *testing.T) {
|
|
root := filepath.Join("..", "..")
|
|
|
|
raw, err := os.ReadFile(filepath.Join(root, "options", "locale", "locale_en-US.json"))
|
|
if err != nil {
|
|
t.Fatalf("read locale: %v", err)
|
|
}
|
|
var locale map[string]any
|
|
if err := json.Unmarshal(raw, &locale); err != nil {
|
|
t.Fatalf("parse locale: %v", err)
|
|
}
|
|
|
|
files, err := filepath.Glob(filepath.Join(".", "tasks*.go"))
|
|
if err != nil {
|
|
t.Fatalf("glob: %v", err)
|
|
}
|
|
|
|
re := regexp.MustCompile(`RegisterTaskFatal\("([^"]+)"`)
|
|
var checked int
|
|
for _, f := range files {
|
|
src, err := os.ReadFile(f)
|
|
if err != nil {
|
|
t.Fatalf("read %s: %v", f, err)
|
|
}
|
|
for _, m := range re.FindAllStringSubmatch(string(src), -1) {
|
|
task := m[1]
|
|
checked++
|
|
if _, ok := locale["admin.dashboard."+task]; !ok {
|
|
t.Errorf("%s registers cron task %q with no locale key "+
|
|
"admin.dashboard.%s — RegisterTaskFatal will abort startup",
|
|
filepath.Base(f), task, task)
|
|
}
|
|
}
|
|
}
|
|
if checked == 0 {
|
|
t.Fatal("found no RegisterTaskFatal calls — the regex or layout changed")
|
|
}
|
|
t.Logf("verified %d registered cron tasks have translations", checked)
|
|
}
|