From b2121fe41fce4a38537c54e238121e4c02ed1c5b Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Fri, 26 Jan 2024 17:55:18 +0800 Subject: [PATCH 1/6] do not delete ActionSchedule --- services/actions/schedule_tasks.go | 12 ++++++++++-- services/repository/setting.go | 13 ++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/services/actions/schedule_tasks.go b/services/actions/schedule_tasks.go index e7aa4a39accfe..48e9de6489c04 100644 --- a/services/actions/schedule_tasks.go +++ b/services/actions/schedule_tasks.go @@ -10,6 +10,7 @@ import ( actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" @@ -65,8 +66,15 @@ func startTasks(ctx context.Context) error { } } - cfg := row.Repo.MustGetUnit(ctx, unit.TypeActions).ActionsConfig() - if cfg.IsWorkflowDisabled(row.Schedule.WorkflowID) { + cfg, err := row.Repo.GetUnit(ctx, unit.TypeActions) + if err != nil { + if repo_model.IsErrUnitTypeNotExist(err) { + // Skip the actions unit of this repo is disabled. + continue + } + return err + } + if cfg.ActionsConfig().IsWorkflowDisabled(row.Schedule.WorkflowID) { continue } diff --git a/services/repository/setting.go b/services/repository/setting.go index 6496ac4014c11..5e792c2598aa4 100644 --- a/services/repository/setting.go +++ b/services/repository/setting.go @@ -5,13 +5,14 @@ package repository import ( "context" + "fmt" "slices" actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/log" + webhook_module "code.gitea.io/gitea/modules/webhook" ) // UpdateRepositoryUnits updates a repository's units @@ -28,8 +29,14 @@ func UpdateRepositoryUnits(ctx context.Context, repo *repo_model.Repository, uni } if slices.Contains(deleteUnitTypes, unit.TypeActions) { - if err := actions_model.CleanRepoScheduleTasks(ctx, repo); err != nil { - log.Error("CleanRepoScheduleTasks: %v", err) + if err := actions_model.CancelRunningJobs( + ctx, + repo.ID, + repo.DefaultBranch, + "", + webhook_module.HookEventSchedule, + ); err != nil { + return fmt.Errorf("CancelRunningJobs: %v", err) } } From e02ed2bf0c7d04b4bb4cc7552d43aeb47b404c73 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Fri, 26 Jan 2024 18:12:52 +0800 Subject: [PATCH 2/6] fix err return --- services/actions/schedule_tasks.go | 2 +- services/repository/setting.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/actions/schedule_tasks.go b/services/actions/schedule_tasks.go index 48e9de6489c04..79dd84e0cc4d8 100644 --- a/services/actions/schedule_tasks.go +++ b/services/actions/schedule_tasks.go @@ -72,7 +72,7 @@ func startTasks(ctx context.Context) error { // Skip the actions unit of this repo is disabled. continue } - return err + return fmt.Errorf("GetUnit: %w", err) } if cfg.ActionsConfig().IsWorkflowDisabled(row.Schedule.WorkflowID) { continue diff --git a/services/repository/setting.go b/services/repository/setting.go index 5e792c2598aa4..c40d73d2405ea 100644 --- a/services/repository/setting.go +++ b/services/repository/setting.go @@ -36,7 +36,7 @@ func UpdateRepositoryUnits(ctx context.Context, repo *repo_model.Repository, uni "", webhook_module.HookEventSchedule, ); err != nil { - return fmt.Errorf("CancelRunningJobs: %v", err) + return fmt.Errorf("CancelRunningJobs: %w", err) } } From d18592ebf8b24770e5458309ed82adf35a6e1fc6 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Mon, 29 Jan 2024 18:40:25 +0800 Subject: [PATCH 3/6] fix import cycle --- routers/api/v1/repo/wiki.go | 4 ++-- services/actions/notifier_helper.go | 5 +++++ services/convert/wiki.go | 15 --------------- services/wiki/wiki_path.go | 15 +++++++++++++++ 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index ba3e978a83531..4f27500496cd2 100644 --- a/routers/api/v1/repo/wiki.go +++ b/routers/api/v1/repo/wiki.go @@ -203,7 +203,7 @@ func getWikiPage(ctx *context.APIContext, wikiName wiki_service.WebPath) *api.Wi } return &api.WikiPage{ - WikiPageMetaData: convert.ToWikiPageMetaData(wikiName, lastCommit, ctx.Repo.Repository), + WikiPageMetaData: wiki_service.ToWikiPageMetaData(wikiName, lastCommit, ctx.Repo.Repository), ContentBase64: content, CommitCount: commitsCount, Sidebar: sidebarContent, @@ -333,7 +333,7 @@ func ListWikiPages(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "WikiFilenameToName", err) return } - pages = append(pages, convert.ToWikiPageMetaData(wikiName, c, ctx.Repo.Repository)) + pages = append(pages, wiki_service.ToWikiPageMetaData(wikiName, c, ctx.Repo.Repository)) } ctx.SetTotalCountHeader(int64(len(entries))) diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 9900de3d2ecdd..2c22099a544b0 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -474,3 +474,8 @@ func handleSchedules( return actions_model.CreateScheduleTask(ctx, crons) } + +func DetactAndHandleSchedules(ctx context.Context, repo *repo_model.Repository) error { + // TODO + return nil +} diff --git a/services/convert/wiki.go b/services/convert/wiki.go index 1f048434832c3..767bfdb88d063 100644 --- a/services/convert/wiki.go +++ b/services/convert/wiki.go @@ -6,11 +6,8 @@ package convert import ( "time" - repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/util" - wiki_service "code.gitea.io/gitea/services/wiki" ) // ToWikiCommit convert a git commit into a WikiCommit @@ -46,15 +43,3 @@ func ToWikiCommitList(commits []*git.Commit, total int64) *api.WikiCommitList { Count: total, } } - -// ToWikiPageMetaData converts meta information to a WikiPageMetaData -func ToWikiPageMetaData(wikiName wiki_service.WebPath, lastCommit *git.Commit, repo *repo_model.Repository) *api.WikiPageMetaData { - subURL := string(wikiName) - _, title := wiki_service.WebPathToUserTitle(wikiName) - return &api.WikiPageMetaData{ - Title: title, - HTMLURL: util.URLJoin(repo.HTMLURL(), "wiki", subURL), - SubURL: subURL, - LastCommit: ToWikiCommit(lastCommit), - } -} diff --git a/services/wiki/wiki_path.go b/services/wiki/wiki_path.go index e51d6c630ca34..74c706404368e 100644 --- a/services/wiki/wiki_path.go +++ b/services/wiki/wiki_path.go @@ -9,7 +9,10 @@ import ( "strings" repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/git" + api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/convert" ) // To define the wiki related concepts: @@ -155,3 +158,15 @@ func UserTitleToWebPath(base, title string) WebPath { } return WebPath(title) } + +// ToWikiPageMetaData converts meta information to a WikiPageMetaData +func ToWikiPageMetaData(wikiName WebPath, lastCommit *git.Commit, repo *repo_model.Repository) *api.WikiPageMetaData { + subURL := string(wikiName) + _, title := WebPathToUserTitle(wikiName) + return &api.WikiPageMetaData{ + Title: title, + HTMLURL: util.URLJoin(repo.HTMLURL(), "wiki", subURL), + SubURL: subURL, + LastCommit: convert.ToWikiCommit(lastCommit), + } +} From 0dc1361591b4f0711854b0b5d0b987975cc399be Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Mon, 29 Jan 2024 18:47:53 +0800 Subject: [PATCH 4/6] detect schedule workflows in when repo setting changes --- services/repository/setting.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/services/repository/setting.go b/services/repository/setting.go index c40d73d2405ea..db5a1c926e4d4 100644 --- a/services/repository/setting.go +++ b/services/repository/setting.go @@ -12,7 +12,8 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" - webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/modules/log" + actions_service "code.gitea.io/gitea/services/actions" ) // UpdateRepositoryUnits updates a repository's units @@ -29,14 +30,17 @@ func UpdateRepositoryUnits(ctx context.Context, repo *repo_model.Repository, uni } if slices.Contains(deleteUnitTypes, unit.TypeActions) { - if err := actions_model.CancelRunningJobs( - ctx, - repo.ID, - repo.DefaultBranch, - "", - webhook_module.HookEventSchedule, - ); err != nil { - return fmt.Errorf("CancelRunningJobs: %w", err) + if err := actions_model.CleanRepoScheduleTasks(ctx, repo); err != nil { + log.Error("CleanRepoScheduleTasks: %v", err) + } + } + + for _, u := range units { + if u.Type == unit.TypeActions { + if err := actions_service.DetectAndHandleSchedules(ctx, repo); err != nil { + return fmt.Errorf("detect and handle schedule workflows: %w", err) + } + break } } From ef92f567d3e552e1d10e7dec7babafcf34b38d71 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 31 Jan 2024 09:28:21 +0800 Subject: [PATCH 5/6] add DetectAndHandleSchedules --- modules/actions/workflows.go | 35 +++++++++++++++++++++++++++++ services/actions/notifier_helper.go | 33 ++++++++++++++++++++++++--- services/repository/setting.go | 3 +-- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index cbc7e011d1d1b..b289bbfeab518 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -146,6 +146,41 @@ func DetectWorkflows( return workflows, schedules, nil } +func DetectScheduledWorkflows(gitRepo *git.Repository, commit *git.Commit) ([]*DetectedWorkflow, error) { + entries, err := ListWorkflows(commit) + if err != nil { + return nil, err + } + + wfs := make([]*DetectedWorkflow, 0, len(entries)) + for _, entry := range entries { + content, err := GetContentFromEntry(entry) + if err != nil { + return nil, err + } + + // one workflow may have multiple events + events, err := GetEventsFromContent(content) + if err != nil { + log.Warn("ignore invalid workflow %q: %v", entry.Name(), err) + continue + } + for _, evt := range events { + log.Trace("detect scheduled workflow: %q", entry.Name()) + if evt.IsSchedule() { + dwf := &DetectedWorkflow{ + EntryName: entry.Name(), + TriggerEvent: evt, + Content: content, + } + wfs = append(wfs, dwf) + } + } + } + + return wfs, nil +} + func detectMatched(gitRepo *git.Repository, commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool { if !canGithubEventMatch(evt.Name, triggedEvent) { return false diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 2c22099a544b0..77173e58a367e 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -475,7 +475,34 @@ func handleSchedules( return actions_model.CreateScheduleTask(ctx, crons) } -func DetactAndHandleSchedules(ctx context.Context, repo *repo_model.Repository) error { - // TODO - return nil +// DetectAndHandleSchedules detects the schedule workflows on the default branch and create schedule tasks +func DetectAndHandleSchedules(ctx context.Context, repo *repo_model.Repository) error { + gitRepo, err := gitrepo.OpenRepository(context.Background(), repo) + if err != nil { + return fmt.Errorf("git.OpenRepository: %w", err) + } + defer gitRepo.Close() + + // Only detect schedule workflows on the default branch + commit, err := gitRepo.GetCommit(repo.DefaultBranch) + if err != nil { + return fmt.Errorf("gitRepo.GetCommit: %w", err) + } + scheduleWorkflows, err := actions_module.DetectScheduledWorkflows(gitRepo, commit) + if err != nil { + return fmt.Errorf("detect schedule workflows: %w", err) + } + if len(scheduleWorkflows) == 0 { + return nil + } + + // We need a notifyInput to call handleSchedules + // Here we use the commit author as the Doer of the notifyInput + commitUser, err := user_model.GetUserByEmail(ctx, commit.Author.Email) + if err != nil { + return fmt.Errorf("get user by email: %w", err) + } + notifyInput := newNotifyInput(repo, commitUser, webhook_module.HookEventSchedule) + + return handleSchedules(ctx, scheduleWorkflows, commit, notifyInput, repo.DefaultBranch) } diff --git a/services/repository/setting.go b/services/repository/setting.go index db5a1c926e4d4..b82f24271ea34 100644 --- a/services/repository/setting.go +++ b/services/repository/setting.go @@ -5,7 +5,6 @@ package repository import ( "context" - "fmt" "slices" actions_model "code.gitea.io/gitea/models/actions" @@ -38,7 +37,7 @@ func UpdateRepositoryUnits(ctx context.Context, repo *repo_model.Repository, uni for _, u := range units { if u.Type == unit.TypeActions { if err := actions_service.DetectAndHandleSchedules(ctx, repo); err != nil { - return fmt.Errorf("detect and handle schedule workflows: %w", err) + log.Error("DetectAndHandleSchedules: %v", err) } break } From 2df2b7f64b2bc06499d246c0d3f00857eb5d74aa Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 31 Jan 2024 12:00:25 +0800 Subject: [PATCH 6/6] fix log --- modules/actions/workflows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index b289bbfeab518..a883f4181b2c8 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -166,8 +166,8 @@ func DetectScheduledWorkflows(gitRepo *git.Repository, commit *git.Commit) ([]*D continue } for _, evt := range events { - log.Trace("detect scheduled workflow: %q", entry.Name()) if evt.IsSchedule() { + log.Trace("detect scheduled workflow: %q", entry.Name()) dwf := &DetectedWorkflow{ EntryName: entry.Name(), TriggerEvent: evt,