fix(worker): commit as the token's account and check it can push
The worker committed as a hard-coded "gbr-bot", and a token without Write access only showed up when a build finished and its push failed. On start it now reads the token's account (GET /user) for the commit author, and refuses to run if that account can't push to the games repo. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
929e7d68d0
commit
f3a2a1f099
3 files changed
+100
-3
No files matched your search
+52
-2
@@ -49,6 +49,53 @@ type workerConfig struct {
|
||||
workDir, name string
|
||||
poll time.Duration
|
||||
provider, model string
|
||||
botLogin, botEmail string // the token's account, used as the commit author
|
||||
}
|
||||
|
||||
// checkBot reads which account GITEA_TOKEN belongs to and makes sure it can push to the games repo, so a
|
||||
// wrong token or missing permission shows when the worker starts, not at the end of a 30-minute build.
|
||||
func (c *workerConfig) checkBot() error {
|
||||
var user struct {
|
||||
Login string `json:"login"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
if err := c.giteaGet("/user", &user); err != nil {
|
||||
return fmt.Errorf("GITEA_TOKEN: %w", err)
|
||||
}
|
||||
var repo struct {
|
||||
Permissions struct {
|
||||
Push bool `json:"push"`
|
||||
} `json:"permissions"`
|
||||
}
|
||||
if err := c.giteaGet("/repos/"+c.repo, &repo); err != nil {
|
||||
return fmt.Errorf("%s: %w", c.repo, err)
|
||||
}
|
||||
if !repo.Permissions.Push {
|
||||
return fmt.Errorf("the account %s can't push to %s: give it Write access there", user.Login, c.repo)
|
||||
}
|
||||
c.botLogin, c.botEmail = user.Login, user.Email
|
||||
if c.botEmail == "" {
|
||||
c.botEmail = user.Login + "@users.noreply"
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *workerConfig) giteaGet(p string, out any) error {
|
||||
req, err := http.NewRequest(http.MethodGet, c.gitea+"/api/v1"+p, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Authorization", "token "+c.botToken)
|
||||
resp, err := (&http.Client{Timeout: 30 * time.Second}).Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode >= 300 {
|
||||
raw, _ := io.ReadAll(resp.Body)
|
||||
return fmt.Errorf("HTTP %d: %.200s", resp.StatusCode, raw)
|
||||
}
|
||||
return json.NewDecoder(resp.Body).Decode(out)
|
||||
}
|
||||
|
||||
func runWorker(args []string) error {
|
||||
@@ -71,7 +118,10 @@ func runWorker(args []string) error {
|
||||
return fmt.Errorf("set %s", v.name)
|
||||
}
|
||||
}
|
||||
fmt.Printf("[worker] %s polling %s every %s\n", c.name, c.panel, c.poll)
|
||||
if err := c.checkBot(); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("[worker] %s polling %s every %s; pull requests as %s\n", c.name, c.panel, c.poll, c.botLogin)
|
||||
for {
|
||||
job, err := c.claim()
|
||||
if err != nil {
|
||||
@@ -313,7 +363,7 @@ func (c *workerConfig) openPR(dir string, job *builderJob, res *buildResult) (st
|
||||
}{
|
||||
{"checkout", []string{"checkout", "-q", "-b", branch}},
|
||||
{"add", []string{"add", filepath.ToSlash(res.Dir)}},
|
||||
{"commit", []string{"-c", "user.name=gbr-bot", "-c", "user.email=gbr-bot@users.noreply.gitea.gbreed.com", "commit", "-q", "-m",
|
||||
{"commit", []string{"-c", "user.name=" + c.botLogin, "-c", "user.email=" + c.botEmail, "commit", "-q", "-m",
|
||||
fmt.Sprintf("feat(games): draft %s\n\nDrafted and boot-tested by the GBR builder (job %s).", job.GameName, job.ID)}},
|
||||
{"push", []string{"-c", auth, "push", "-q", "origin", branch}},
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user