Skip to content

Commit adc3598

Browse files
authored
Fix an actions schedule bug (#28942)
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
1 parent 0b1a42c commit adc3598

File tree

7 files changed

+104
-19
lines changed

7 files changed

+104
-19
lines changed

modules/actions/workflows.go

+35
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

+2-2
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ func getWikiPage(ctx *context.APIContext, wikiName wiki_service.WebPath) *api.Wi
203203
}
204204

205205
return &api.WikiPage{
206-
WikiPageMetaData: convert.ToWikiPageMetaData(wikiName, lastCommit, ctx.Repo.Repository),
206+
WikiPageMetaData: wiki_service.ToWikiPageMetaData(wikiName, lastCommit, ctx.Repo.Repository),
207207
ContentBase64: content,
208208
CommitCount: commitsCount,
209209
Sidebar: sidebarContent,
@@ -333,7 +333,7 @@ func ListWikiPages(ctx *context.APIContext) {
333333
ctx.Error(http.StatusInternalServerError, "WikiFilenameToName", err)
334334
return
335335
}
336-
pages = append(pages, convert.ToWikiPageMetaData(wikiName, c, ctx.Repo.Repository))
336+
pages = append(pages, wiki_service.ToWikiPageMetaData(wikiName, c, ctx.Repo.Repository))
337337
}
338338

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

services/actions/notifier_helper.go

+32
Original file line numberDiff line numberDiff line change
@@ -474,3 +474,35 @@ func handleSchedules(
474474

475475
return actions_model.CreateScheduleTask(ctx, crons)
476476
}
477+
478+
// DetectAndHandleSchedules detects the schedule workflows on the default branch and create schedule tasks
479+
func DetectAndHandleSchedules(ctx context.Context, repo *repo_model.Repository) error {
480+
gitRepo, err := gitrepo.OpenRepository(context.Background(), repo)
481+
if err != nil {
482+
return fmt.Errorf("git.OpenRepository: %w", err)
483+
}
484+
defer gitRepo.Close()
485+
486+
// Only detect schedule workflows on the default branch
487+
commit, err := gitRepo.GetCommit(repo.DefaultBranch)
488+
if err != nil {
489+
return fmt.Errorf("gitRepo.GetCommit: %w", err)
490+
}
491+
scheduleWorkflows, err := actions_module.DetectScheduledWorkflows(gitRepo, commit)
492+
if err != nil {
493+
return fmt.Errorf("detect schedule workflows: %w", err)
494+
}
495+
if len(scheduleWorkflows) == 0 {
496+
return nil
497+
}
498+
499+
// We need a notifyInput to call handleSchedules
500+
// Here we use the commit author as the Doer of the notifyInput
501+
commitUser, err := user_model.GetUserByEmail(ctx, commit.Author.Email)
502+
if err != nil {
503+
return fmt.Errorf("get user by email: %w", err)
504+
}
505+
notifyInput := newNotifyInput(repo, commitUser, webhook_module.HookEventSchedule)
506+
507+
return handleSchedules(ctx, scheduleWorkflows, commit, notifyInput, repo.DefaultBranch)
508+
}

services/actions/schedule_tasks.go

+10-2
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

-15
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
// ToWikiCommit convert a git commit into a WikiCommit
@@ -46,15 +43,3 @@ func ToWikiCommitList(commits []*git.Commit, total int64) *api.WikiCommitList {
4643
Count: total,
4744
}
4845
}
49-
50-
// ToWikiPageMetaData converts meta information to a WikiPageMetaData
51-
func ToWikiPageMetaData(wikiName wiki_service.WebPath, lastCommit *git.Commit, repo *repo_model.Repository) *api.WikiPageMetaData {
52-
subURL := string(wikiName)
53-
_, title := wiki_service.WebPathToUserTitle(wikiName)
54-
return &api.WikiPageMetaData{
55-
Title: title,
56-
HTMLURL: util.URLJoin(repo.HTMLURL(), "wiki", subURL),
57-
SubURL: subURL,
58-
LastCommit: ToWikiCommit(lastCommit),
59-
}
60-
}

services/repository/setting.go

+10
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

+15
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+
// ToWikiPageMetaData converts meta information to a WikiPageMetaData
163+
func ToWikiPageMetaData(wikiName WebPath, lastCommit *git.Commit, repo *repo_model.Repository) *api.WikiPageMetaData {
164+
subURL := string(wikiName)
165+
_, title := WebPathToUserTitle(wikiName)
166+
return &api.WikiPageMetaData{
167+
Title: title,
168+
HTMLURL: util.URLJoin(repo.HTMLURL(), "wiki", subURL),
169+
SubURL: subURL,
170+
LastCommit: convert.ToWikiCommit(lastCommit),
171+
}
172+
}

0 commit comments

Comments
 (0)