aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2026-01-29 09:32:25 +0100
committerDmitry Vyukov <dvyukov@google.com>2026-01-30 11:03:40 +0000
commitae7dc18c2a1cb76ec4d3f158ba5f503ed91ac1b6 (patch)
tree106da0f9bf81d036f33aff9a01eec5e6d43f9025
parent6adbdcbe0a33024c6e70ffccd1c76f62a0179098 (diff)
dashboard/app: upload AI-generated patches to gerrit
-rw-r--r--dashboard/app/ai.go36
1 files changed, 34 insertions, 2 deletions
diff --git a/dashboard/app/ai.go b/dashboard/app/ai.go
index bd01b0ea6..970d3f588 100644
--- a/dashboard/app/ai.go
+++ b/dashboard/app/ai.go
@@ -17,10 +17,13 @@ import (
"github.com/google/syzkaller/dashboard/app/aidb"
"github.com/google/syzkaller/dashboard/dashapi"
"github.com/google/syzkaller/pkg/aflow/ai"
+ "github.com/google/syzkaller/pkg/email"
+ "github.com/google/syzkaller/pkg/gerrit"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/pkg/report/crash"
"github.com/google/syzkaller/pkg/vcs"
db "google.golang.org/appengine/v2/datastore"
+ "google.golang.org/appengine/v2/log"
)
const AIAccessLevel = AccessUser
@@ -389,8 +392,15 @@ func apiAIJobDone(ctx context.Context, req *dashapi.AIJobDoneReq) (any, error) {
if len(req.Results) != 0 {
job.Results = spanner.NullJSON{Value: req.Results, Valid: true}
}
- err = aiJobUpdate(ctx, job)
- return nil, err
+ if err = aiJobUpdate(ctx, job); err != nil {
+ return nil, err
+ }
+ if job.Type == ai.WorkflowPatching && job.BugID.Valid && job.Finished.Valid && job.Error == "" {
+ if err := createGerritChange(ctx, job); err != nil {
+ log.Errorf(ctx, "failed to create gerrit change for job %v: %v", job.ID, err)
+ }
+ }
+ return nil, nil
}
func aiJobUpdate(ctx context.Context, job *aidb.Job) error {
@@ -665,6 +675,28 @@ func workflowsForBug(bug *Bug, manual bool) map[ai.WorkflowType]bool {
return workflows
}
+func createGerritChange(ctx context.Context, job *aidb.Job) error {
+ res, err := castJobResults[ai.PatchingOutputs](job)
+ if err != nil {
+ return err
+ }
+ // TODO: add Reported-by tag for the syzbot bug, or a link to lore report.
+ // Add Fixes tag if we have cause bisection, but we need to verify it with LLMs
+ // somehow since lots of them are wrong.
+ // Probably shouldn't cc stable for all patches (e.g. removing a WARNING)?
+ res.Recipients = append(res.Recipients, ai.Recipient{Email: "stable@vger.kernel.org"})
+ // TODO: move these constants to config.
+ const author = "syzbot@kernel.org"
+ description := email.FormatPatchDescription(res.PatchDescription, []string{author}, res.Recipients)
+ changeID, link, err := gerrit.CreateChange(ctx, res.KernelRepo, res.KernelBranch,
+ res.KernelCommit, description, res.PatchDiff)
+ if err != nil {
+ return err
+ }
+ log.Infof(ctx, "created gerrit change %v for job %v: %v", changeID, job.ID, link)
+ return nil
+}
+
const (
aiCorrectnessCorrect = "✅"
aiCorrectnessIncorrect = "❌"