1
0
mirror of https://github.com/go-gitea/gitea.git synced 2025-04-18 00:47:48 -04:00
gitea/models/bots/run.go
2022-11-25 17:48:44 +08:00

163 lines
3.8 KiB
Go

// Copyright 2022 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package bots
import (
"context"
"fmt"
"hash/fnv"
"code.gitea.io/gitea/core"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/timeutil"
"github.com/nektos/act/pkg/jobparser"
)
// Run represents a run of a workflow file
type Run struct {
ID int64
Name string
RepoID int64 `xorm:"index unique(repo_workflow_index)"`
Repo *repo_model.Repository `xorm:"-"`
WorkflowID string `xorm:"index unique(repo_workflow_index)"` // the name of workflow file
Index int64 `xorm:"index unique(repo_workflow_index)"` // a unique number for each run of a particular workflow in a repository
TriggerUserID int64
TriggerUser *user_model.User `xorm:"-"`
Ref string
CommitSHA string
Event webhook.HookEventType
Token string // token for this task
Grant string // permissions for this task
EventPayload string `xorm:"LONGTEXT"`
Status core.BuildStatus `xorm:"index"`
StartTime timeutil.TimeStamp
EndTime timeutil.TimeStamp
Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated"`
}
func init() {
db.RegisterModel(new(Run))
db.RegisterModel(new(RunIndex))
}
func (Run) TableName() string {
return "bots_run"
}
// LoadAttributes load Repo TriggerUser if not loaded
func (r *Run) LoadAttributes(ctx context.Context) error {
if r == nil {
return nil
}
if r.Repo == nil {
repo, err := repo_model.GetRepositoryByIDCtx(ctx, r.RepoID)
if err != nil {
return err
}
r.Repo = repo
}
if err := r.Repo.LoadAttributes(ctx); err != nil {
return err
}
if r.TriggerUser == nil {
u, err := user_model.GetUserByIDCtx(ctx, r.TriggerUserID)
if err != nil {
return err
}
r.TriggerUser = u
}
return nil
}
// InsertRun inserts a bot run
func InsertRun(run *Run, jobs []*jobparser.SingleWorkflow) error {
var groupId int64
{
// tricky way to get resource group id
h := fnv.New64()
_, _ = h.Write([]byte(fmt.Sprintf("%d_%s", run.RepoID, run.WorkflowID)))
groupId = int64(h.Sum64())
}
index, err := db.GetNextResourceIndex("bots_run_index", groupId)
if err != nil {
return err
}
run.Index = index
ctx, commiter, err := db.TxContext()
if err != nil {
return err
}
defer commiter.Close()
if err := db.Insert(ctx, run); err != nil {
return err
}
runJobs := make([]*RunJob, 0, len(jobs))
for _, v := range jobs {
id, job := v.Job()
payload, _ := v.Marshal()
runJobs = append(runJobs, &RunJob{
RunID: run.ID,
Name: job.Name,
Ready: true, // TODO: should be false if there are needs to satisfy
WorkflowPayload: payload,
JobID: id,
Needs: nil, // TODO: analyse needs
RunsOn: job.RunsOn(),
TaskID: 0,
Status: core.StatusPending,
})
}
if err := db.Insert(ctx, runJobs); err != nil {
return err
}
if err := commiter.Commit(); err != nil {
return err
}
return nil
}
// ErrRunNotExist represents an error for bot run not exist
type ErrRunNotExist struct {
ID int64
}
func (err ErrRunNotExist) Error() string {
return fmt.Sprintf("run [%d] is not exist", err.ID)
}
func GetRunByID(ctx context.Context, id int64) (*Run, error) {
var run Run
has, err := db.GetEngine(ctx).Where("id=?", id).Get(&run)
if err != nil {
return nil, err
} else if !has {
return nil, ErrRunNotExist{
ID: id,
}
}
return &run, nil
}
type RunIndex db.ResourceIndex
func (RunIndex) TableName() string {
return "bots_run_index"
}