Skip to content

Commit c398c25

Browse files
GiteaBotZettat123lunny
authored
Fix an actions schedule bug (#28942) (#28999)
Backport #28942 by @Zettat123 In #28691, schedule plans will be deleted when a repo's actions unit is disabled. But when the unit is enabled, the schedule plans won't be created again. This PR fixes the bug. The schedule plans will be created again when the actions unit is re-enabled --------- Co-authored-by: Zettat123 <[email protected]> Co-authored-by: Lunny Xiao <[email protected]>
1 parent 2048363 commit c398c25

File tree

7 files changed

+104
-19
lines changed

7 files changed

+104
-19
lines changed

modules/actions/workflows.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,41 @@ func DetectWorkflows(
146146
return workflows, schedules, nil
147147
}
148148

149+
func DetectScheduledWorkflows(gitRepo *git.Repository, commit *git.Commit) ([]*DetectedWorkflow, error) {
150+
entries, err := ListWorkflows(commit)
151+
if err != nil {
152+
return nil, err
153+
}
154+
155+
wfs := make([]*DetectedWorkflow, 0, len(entries))
156+
for _, entry := range entries {
157+
content, err := GetContentFromEntry(entry)
158+
if err != nil {
159+
return nil, err
160+
}
161+
162+
// one workflow may have multiple events
163+
events, err := GetEventsFromContent(content)
164+
if err != nil {
165+
log.Warn("ignore invalid workflow %q: %v", entry.Name(), err)
166+
continue
167+
}
168+
for _, evt := range events {
169+
if evt.IsSchedule() {
170+
log.Trace("detect scheduled workflow: %q", entry.Name())
171+
dwf := &DetectedWorkflow{
172+
EntryName: entry.Name(),
173+
TriggerEvent: evt,
174+
Content: content,
175+
}
176+
wfs = append(wfs, dwf)
177+
}
178+
}
179+
}
180+
181+
return wfs, nil
182+
}
183+
149184
func detectMatched(gitRepo *git.Repository, commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool {
150185
if !canGithubEventMatch(evt.Name, triggedEvent) {
151186
return false

routers/api/v1/repo/wiki.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ func getUncycloPage(ctx *context.APIContext, wikiName wiki_service.WebPath) *api.Wi
198198
}
199199

200200
return &api.UncycloPage{
201-
UncycloPageMetaData: convert.ToUncycloPageMetaData(wikiName, lastCommit, ctx.Repo.Repository),
201+
UncycloPageMetaData: wiki_service.ToUncycloPageMetaData(wikiName, lastCommit, ctx.Repo.Repository),
202202
ContentBase64: content,
203203
CommitCount: commitsCount,
204204
Sidebar: sidebarContent,
@@ -326,7 +326,7 @@ func ListUncycloPages(ctx *context.APIContext) {
326326
ctx.Error(http.StatusInternalServerError, "UncycloFilenameToName", err)
327327
return
328328
}
329-
pages = append(pages, convert.ToUncycloPageMetaData(wikiName, c, ctx.Repo.Repository))
329+
pages = append(pages, wiki_service.ToUncycloPageMetaData(wikiName, c, ctx.Repo.Repository))
330330
}
331331

332332
ctx.SetTotalCountHeader(int64(len(entries)))

services/actions/notifier_helper.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,3 +447,35 @@ func handleSchedules(
447447

448448
return actions_model.CreateScheduleTask(ctx, crons)
449449
}
450+
451+
// DetectAndHandleSchedules detects the schedule workflows on the default branch and create schedule tasks
452+
func DetectAndHandleSchedules(ctx context.Context, repo *repo_model.Repository) error {
453+
gitRepo, err := git.OpenRepository(context.Background(), repo.RepoPath())
454+
if err != nil {
455+
return fmt.Errorf("git.OpenRepository: %w", err)
456+
}
457+
defer gitRepo.Close()
458+
459+
// Only detect schedule workflows on the default branch
460+
commit, err := gitRepo.GetCommit(repo.DefaultBranch)
461+
if err != nil {
462+
return fmt.Errorf("gitRepo.GetCommit: %w", err)
463+
}
464+
scheduleWorkflows, err := actions_module.DetectScheduledWorkflows(gitRepo, commit)
465+
if err != nil {
466+
return fmt.Errorf("detect schedule workflows: %w", err)
467+
}
468+
if len(scheduleWorkflows) == 0 {
469+
return nil
470+
}
471+
472+
// We need a notifyInput to call handleSchedules
473+
// Here we use the commit author as the Doer of the notifyInput
474+
commitUser, err := user_model.GetUserByEmail(ctx, commit.Author.Email)
475+
if err != nil {
476+
return fmt.Errorf("get user by email: %w", err)
477+
}
478+
notifyInput := newNotifyInput(repo, commitUser, webhook_module.HookEventSchedule)
479+
480+
return handleSchedules(ctx, scheduleWorkflows, commit, notifyInput, repo.DefaultBranch)
481+
}

services/actions/schedule_tasks.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
actions_model "code.gitea.io/gitea/models/actions"
1212
"code.gitea.io/gitea/models/db"
13+
repo_model "code.gitea.io/gitea/models/repo"
1314
"code.gitea.io/gitea/models/unit"
1415
"code.gitea.io/gitea/modules/log"
1516
"code.gitea.io/gitea/modules/timeutil"
@@ -65,8 +66,15 @@ func startTasks(ctx context.Context) error {
6566
}
6667
}
6768

68-
cfg := row.Repo.MustGetUnit(ctx, unit.TypeActions).ActionsConfig()
69-
if cfg.IsWorkflowDisabled(row.Schedule.WorkflowID) {
69+
cfg, err := row.Repo.GetUnit(ctx, unit.TypeActions)
70+
if err != nil {
71+
if repo_model.IsErrUnitTypeNotExist(err) {
72+
// Skip the actions unit of this repo is disabled.
73+
continue
74+
}
75+
return fmt.Errorf("GetUnit: %w", err)
76+
}
77+
if cfg.ActionsConfig().IsWorkflowDisabled(row.Schedule.WorkflowID) {
7078
continue
7179
}
7280

services/convert/wiki.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@ package convert
66
import (
77
"time"
88

9-
repo_model "code.gitea.io/gitea/models/repo"
109
"code.gitea.io/gitea/modules/git"
1110
api "code.gitea.io/gitea/modules/structs"
12-
"code.gitea.io/gitea/modules/util"
13-
wiki_service "code.gitea.io/gitea/services/wiki"
1411
)
1512

1613
// ToUncycloCommit convert a git commit into a UncycloCommit
@@ -46,15 +43,3 @@ func ToUncycloCommitList(commits []*git.Commit, total int64) *api.UncycloCommitList {
4643
Count: total,
4744
}
4845
}
49-
50-
// ToUncycloPageMetaData converts meta information to a UncycloPageMetaData
51-
func ToUncycloPageMetaData(wikiName wiki_service.WebPath, lastCommit *git.Commit, repo *repo_model.Repository) *api.UncycloPageMetaData {
52-
subURL := string(wikiName)
53-
_, title := wiki_service.WebPathToUserTitle(wikiName)
54-
return &api.UncycloPageMetaData{
55-
Title: title,
56-
HTMLURL: util.URLJoin(repo.HTMLURL(), "wiki", subURL),
57-
SubURL: subURL,
58-
LastCommit: ToUncycloCommit(lastCommit),
59-
}
60-
}

services/repository/setting.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
repo_model "code.gitea.io/gitea/models/repo"
1313
"code.gitea.io/gitea/models/unit"
1414
"code.gitea.io/gitea/modules/log"
15+
actions_service "code.gitea.io/gitea/services/actions"
1516
)
1617

1718
// UpdateRepositoryUnits updates a repository's units
@@ -33,6 +34,15 @@ func UpdateRepositoryUnits(ctx context.Context, repo *repo_model.Repository, uni
3334
}
3435
}
3536

37+
for _, u := range units {
38+
if u.Type == unit.TypeActions {
39+
if err := actions_service.DetectAndHandleSchedules(ctx, repo); err != nil {
40+
log.Error("DetectAndHandleSchedules: %v", err)
41+
}
42+
break
43+
}
44+
}
45+
3646
if _, err = db.GetEngine(ctx).Where("repo_id = ?", repo.ID).In("type", deleteUnitTypes).Delete(new(repo_model.RepoUnit)); err != nil {
3747
return err
3848
}

services/wiki/wiki_path.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import (
99
"strings"
1010

1111
repo_model "code.gitea.io/gitea/models/repo"
12+
"code.gitea.io/gitea/modules/git"
13+
api "code.gitea.io/gitea/modules/structs"
1214
"code.gitea.io/gitea/modules/util"
15+
"code.gitea.io/gitea/services/convert"
1316
)
1417

1518
// To define the wiki related concepts:
@@ -155,3 +158,15 @@ func UserTitleToWebPath(base, title string) WebPath {
155158
}
156159
return WebPath(title)
157160
}
161+
162+
// ToUncycloPageMetaData converts meta information to a UncycloPageMetaData
163+
func ToUncycloPageMetaData(wikiName WebPath, lastCommit *git.Commit, repo *repo_model.Repository) *api.UncycloPageMetaData {
164+
subURL := string(wikiName)
165+
_, title := WebPathToUserTitle(wikiName)
166+
return &api.UncycloPageMetaData{
167+
Title: title,
168+
HTMLURL: util.URLJoin(repo.HTMLURL(), "wiki", subURL),
169+
SubURL: subURL,
170+
LastCommit: convert.ToUncycloCommit(lastCommit),
171+
}
172+
}

0 commit comments

Comments
 (0)