Merge pull request 'fix(worker): start with a repository-only token' (#12) from fix/worker-repo-scope-token into main
Builder image / publish (push) Successful in 22s
Validate game templates / validate (push) Successful in 24s
Validate game templates / boot-test (push) Skipped
Validate game templates / publish (push) Skipped

Reviewed-on: #12
This commit was merged in pull request #12.
This commit is contained in:
greg committed 2026-10-25 21:18:40 +00:00
commit dd92b6be4c
3 files changed
+30 -1

No files matched your search

+1
View File
@@ -46,6 +46,7 @@ All through environment variables; nothing about where it runs lives in this rep
| `OLLAMA_URL` | Ollama for the model (or `MODEL_PROVIDER=gemini` with `GEMINI_API_KEY`) | | `OLLAMA_URL` | Ollama for the model (or `MODEL_PROVIDER=gemini` with `GEMINI_API_KEY`) |
| `SEARXNG_URL`, `READER_URL` | A SearXNG instance (JSON API) and a page-to-text reader (`READER_URL/<page url>`) | | `SEARXNG_URL`, `READER_URL` | A SearXNG instance (JSON API) and a page-to-text reader (`READER_URL/<page url>`) |
| `MODEL`, `POLL_INTERVAL`, `WORKER_NAME`, `WORK_DIR` | Optional: model name, poll interval (20s), name shown in the panel, work folder | | `MODEL`, `POLL_INTERVAL`, `WORKER_NAME`, `WORK_DIR` | Optional: model name, poll interval (20s), name shown in the panel, work folder |
| `BOT_NAME` | Optional: commit author when the token can't read its own account (no `read:user` scope); default `gbr-bot` |
## Running a build by hand ## Running a build by hand
+6 -1
View File
@@ -60,7 +60,12 @@ func (c *workerConfig) checkBot() error {
Email string `json:"email"` Email string `json:"email"`
} }
if err := c.giteaGet("/user", &user); err != nil { if err := c.giteaGet("/user", &user); err != nil {
return fmt.Errorf("GITEA_TOKEN: %w", err) if !strings.HasPrefix(err.Error(), "HTTP 403") {
return fmt.Errorf("GITEA_TOKEN: %w", err)
}
// A repository-only token (all the worker needs) may not read its own account: name the author from
// BOT_NAME instead. Whether it can push is still checked below.
user.Login = envOr("BOT_NAME", "gbr-bot")
} }
var repo struct { var repo struct {
Permissions struct { Permissions struct {
+23
View File
@@ -45,3 +45,26 @@ func TestCheckBotNeedsPushAccess(t *testing.T) {
t.Errorf("bad token: got %v", err) t.Errorf("bad token: got %v", err)
} }
} }
func TestCheckBotWithRepositoryOnlyToken(t *testing.T) {
// Gitea answers /user with 403 when the token only has repository scope
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/v1/user":
w.WriteHeader(http.StatusForbidden)
w.Write([]byte(`{"message":"token does not have at least one of required scope(s), required=[read:user]"}`))
case "/api/v1/repos/org/games":
w.Write([]byte(`{"permissions":{"push":true}}`))
}
}))
defer srv.Close()
t.Setenv("BOT_NAME", "gbr-bot")
c := &workerConfig{gitea: srv.URL, repo: "org/games", botToken: "secret"}
if err := c.checkBot(); err != nil {
t.Fatal(err)
}
if c.botLogin != "gbr-bot" || c.botEmail != "gbr-bot@users.noreply" {
t.Errorf("identity = %s <%s>", c.botLogin, c.botEmail)
}
}