gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package actions
  4. import (
  5. "context"
  6. "fmt"
  7. "time"
  8. "code.gitea.io/gitea/models/db"
  9. repo_model "code.gitea.io/gitea/models/repo"
  10. user_model "code.gitea.io/gitea/models/user"
  11. "code.gitea.io/gitea/modules/timeutil"
  12. "code.gitea.io/gitea/modules/util"
  13. webhook_module "code.gitea.io/gitea/modules/webhook"
  14. )
  15. // ActionSchedule represents a schedule of a workflow file
  16. type ActionSchedule struct {
  17. ID int64
  18. Title string
  19. Specs []string
  20. RepoID int64 `xorm:"index"`
  21. Repo *repo_model.Repository `xorm:"-"`
  22. OwnerID int64 `xorm:"index"`
  23. WorkflowID string
  24. TriggerUserID int64
  25. TriggerUser *user_model.User `xorm:"-"`
  26. Ref string
  27. CommitSHA string
  28. Event webhook_module.HookEventType
  29. EventPayload string `xorm:"LONGTEXT"`
  30. Content []byte
  31. Created timeutil.TimeStamp `xorm:"created"`
  32. Updated timeutil.TimeStamp `xorm:"updated"`
  33. }
  34. func init() {
  35. db.RegisterModel(new(ActionSchedule))
  36. }
  37. // GetSchedulesMapByIDs returns the schedules by given id slice.
  38. func GetSchedulesMapByIDs(ctx context.Context, ids []int64) (map[int64]*ActionSchedule, error) {
  39. schedules := make(map[int64]*ActionSchedule, len(ids))
  40. if len(ids) == 0 {
  41. return schedules, nil
  42. }
  43. return schedules, db.GetEngine(ctx).In("id", ids).Find(&schedules)
  44. }
  45. // CreateScheduleTask creates new schedule task.
  46. func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error {
  47. // Return early if there are no rows to insert
  48. if len(rows) == 0 {
  49. return nil
  50. }
  51. return db.WithTx(ctx, func(ctx context.Context) error {
  52. // Loop through each schedule row
  53. for _, row := range rows {
  54. row.Title = util.EllipsisDisplayString(row.Title, 255)
  55. // Create new schedule row
  56. if err := db.Insert(ctx, row); err != nil {
  57. return err
  58. }
  59. // Loop through each schedule spec and create a new spec row
  60. now := time.Now()
  61. for _, spec := range row.Specs {
  62. specRow := &ActionScheduleSpec{
  63. RepoID: row.RepoID,
  64. ScheduleID: row.ID,
  65. Spec: spec,
  66. }
  67. // Parse the spec and check for errors
  68. schedule, err := specRow.Parse()
  69. if err != nil {
  70. continue // skip to the next spec if there's an error
  71. }
  72. specRow.Next = timeutil.TimeStamp(schedule.Next(now).Unix())
  73. // Insert the new schedule spec row
  74. if err = db.Insert(ctx, specRow); err != nil {
  75. return err
  76. }
  77. }
  78. }
  79. return nil
  80. })
  81. }
  82. func DeleteScheduleTaskByRepo(ctx context.Context, id int64) error {
  83. return db.WithTx(ctx, func(ctx context.Context) error {
  84. if _, err := db.GetEngine(ctx).Delete(&ActionSchedule{RepoID: id}); err != nil {
  85. return err
  86. }
  87. if _, err := db.GetEngine(ctx).Delete(&ActionScheduleSpec{RepoID: id}); err != nil {
  88. return err
  89. }
  90. return nil
  91. })
  92. }
  93. func CleanRepoScheduleTasks(ctx context.Context, repo *repo_model.Repository) ([]*ActionRunJob, error) {
  94. // If actions disabled when there is schedule task, this will remove the outdated schedule tasks
  95. // There is no other place we can do this because the app.ini will be changed manually
  96. if err := DeleteScheduleTaskByRepo(ctx, repo.ID); err != nil {
  97. return nil, fmt.Errorf("DeleteCronTaskByRepo: %v", err)
  98. }
  99. // cancel running cron jobs of this repository and delete old schedules
  100. jobs, err := CancelPreviousJobs(
  101. ctx,
  102. repo.ID,
  103. repo.DefaultBranch,
  104. "",
  105. webhook_module.HookEventSchedule,
  106. )
  107. if err != nil {
  108. return jobs, fmt.Errorf("CancelPreviousJobs: %v", err)
  109. }
  110. return jobs, nil
  111. }