2023-08-24 11:06:51 +08:00
|
|
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
|
|
package actions
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-01-13 05:50:38 +08:00
|
|
|
"fmt"
|
2023-08-24 11:06:51 +08:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"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/modules/timeutil"
|
2024-11-14 15:19:14 +08:00
|
|
|
"code.gitea.io/gitea/modules/util"
|
2023-08-24 11:06:51 +08:00
|
|
|
webhook_module "code.gitea.io/gitea/modules/webhook"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ActionSchedule represents a schedule of a workflow file
|
|
|
|
type ActionSchedule struct {
|
|
|
|
ID int64
|
|
|
|
Title string
|
|
|
|
Specs []string
|
|
|
|
RepoID int64 `xorm:"index"`
|
|
|
|
Repo *repo_model.Repository `xorm:"-"`
|
|
|
|
OwnerID int64 `xorm:"index"`
|
|
|
|
WorkflowID string
|
|
|
|
TriggerUserID int64
|
|
|
|
TriggerUser *user_model.User `xorm:"-"`
|
|
|
|
Ref string
|
|
|
|
CommitSHA string
|
|
|
|
Event webhook_module.HookEventType
|
|
|
|
EventPayload string `xorm:"LONGTEXT"`
|
|
|
|
Content []byte
|
|
|
|
Created timeutil.TimeStamp `xorm:"created"`
|
|
|
|
Updated timeutil.TimeStamp `xorm:"updated"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
db.RegisterModel(new(ActionSchedule))
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetSchedulesMapByIDs returns the schedules by given id slice.
|
2023-09-16 22:39:12 +08:00
|
|
|
func GetSchedulesMapByIDs(ctx context.Context, ids []int64) (map[int64]*ActionSchedule, error) {
|
2023-08-24 11:06:51 +08:00
|
|
|
schedules := make(map[int64]*ActionSchedule, len(ids))
|
2023-09-16 22:39:12 +08:00
|
|
|
return schedules, db.GetEngine(ctx).In("id", ids).Find(&schedules)
|
2023-08-24 11:06:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetReposMapByIDs returns the repos by given id slice.
|
2023-09-16 22:39:12 +08:00
|
|
|
func GetReposMapByIDs(ctx context.Context, ids []int64) (map[int64]*repo_model.Repository, error) {
|
2023-08-24 11:06:51 +08:00
|
|
|
repos := make(map[int64]*repo_model.Repository, len(ids))
|
2023-09-16 22:39:12 +08:00
|
|
|
return repos, db.GetEngine(ctx).In("id", ids).Find(&repos)
|
2023-08-24 11:06:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// CreateScheduleTask creates new schedule task.
|
|
|
|
func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error {
|
|
|
|
// Return early if there are no rows to insert
|
|
|
|
if len(rows) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Begin transaction
|
|
|
|
ctx, committer, err := db.TxContext(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer committer.Close()
|
|
|
|
|
|
|
|
// Loop through each schedule row
|
|
|
|
for _, row := range rows {
|
2024-11-14 15:19:14 +08:00
|
|
|
row.Title, _ = util.SplitStringAtByteN(row.Title, 255)
|
2023-08-24 11:06:51 +08:00
|
|
|
// Create new schedule row
|
|
|
|
if err = db.Insert(ctx, row); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Loop through each schedule spec and create a new spec row
|
|
|
|
now := time.Now()
|
|
|
|
|
|
|
|
for _, spec := range row.Specs {
|
Use UTC as default timezone when schedule Actions cron tasks (#31742)
Fix #31657.
According to the
[doc](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onschedule)
of GitHub Actions, The timezone for cron should be UTC, not the local
timezone. And Gitea Actions doesn't have any reasons to change this, so
I think it's a bug.
However, Gitea Actions has extended the syntax, as it supports
descriptors like `@weekly` and `@every 5m`, and supports specifying the
timezone like `TZ=UTC 0 10 * * *`. So we can make it use UTC only when
the timezone is not specified, to be compatible with GitHub Actions, and
also respect the user's specified.
It does break the feature because the times to run tasks would be
changed, and it may confuse users. So I don't think we should backport
this.
## ⚠️ BREAKING ⚠️
If the server's local time zone is not UTC, a scheduled task would run
at a different time after upgrading Gitea to this version.
2024-08-01 18:02:46 +08:00
|
|
|
specRow := &ActionScheduleSpec{
|
|
|
|
RepoID: row.RepoID,
|
|
|
|
ScheduleID: row.ID,
|
|
|
|
Spec: spec,
|
|
|
|
}
|
2023-08-24 11:06:51 +08:00
|
|
|
// Parse the spec and check for errors
|
Use UTC as default timezone when schedule Actions cron tasks (#31742)
Fix #31657.
According to the
[doc](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onschedule)
of GitHub Actions, The timezone for cron should be UTC, not the local
timezone. And Gitea Actions doesn't have any reasons to change this, so
I think it's a bug.
However, Gitea Actions has extended the syntax, as it supports
descriptors like `@weekly` and `@every 5m`, and supports specifying the
timezone like `TZ=UTC 0 10 * * *`. So we can make it use UTC only when
the timezone is not specified, to be compatible with GitHub Actions, and
also respect the user's specified.
It does break the feature because the times to run tasks would be
changed, and it may confuse users. So I don't think we should backport
this.
## ⚠️ BREAKING ⚠️
If the server's local time zone is not UTC, a scheduled task would run
at a different time after upgrading Gitea to this version.
2024-08-01 18:02:46 +08:00
|
|
|
schedule, err := specRow.Parse()
|
2023-08-24 11:06:51 +08:00
|
|
|
if err != nil {
|
|
|
|
continue // skip to the next spec if there's an error
|
|
|
|
}
|
|
|
|
|
Use UTC as default timezone when schedule Actions cron tasks (#31742)
Fix #31657.
According to the
[doc](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onschedule)
of GitHub Actions, The timezone for cron should be UTC, not the local
timezone. And Gitea Actions doesn't have any reasons to change this, so
I think it's a bug.
However, Gitea Actions has extended the syntax, as it supports
descriptors like `@weekly` and `@every 5m`, and supports specifying the
timezone like `TZ=UTC 0 10 * * *`. So we can make it use UTC only when
the timezone is not specified, to be compatible with GitHub Actions, and
also respect the user's specified.
It does break the feature because the times to run tasks would be
changed, and it may confuse users. So I don't think we should backport
this.
## ⚠️ BREAKING ⚠️
If the server's local time zone is not UTC, a scheduled task would run
at a different time after upgrading Gitea to this version.
2024-08-01 18:02:46 +08:00
|
|
|
specRow.Next = timeutil.TimeStamp(schedule.Next(now).Unix())
|
|
|
|
|
2023-08-24 11:06:51 +08:00
|
|
|
// Insert the new schedule spec row
|
Use UTC as default timezone when schedule Actions cron tasks (#31742)
Fix #31657.
According to the
[doc](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onschedule)
of GitHub Actions, The timezone for cron should be UTC, not the local
timezone. And Gitea Actions doesn't have any reasons to change this, so
I think it's a bug.
However, Gitea Actions has extended the syntax, as it supports
descriptors like `@weekly` and `@every 5m`, and supports specifying the
timezone like `TZ=UTC 0 10 * * *`. So we can make it use UTC only when
the timezone is not specified, to be compatible with GitHub Actions, and
also respect the user's specified.
It does break the feature because the times to run tasks would be
changed, and it may confuse users. So I don't think we should backport
this.
## ⚠️ BREAKING ⚠️
If the server's local time zone is not UTC, a scheduled task would run
at a different time after upgrading Gitea to this version.
2024-08-01 18:02:46 +08:00
|
|
|
if err = db.Insert(ctx, specRow); err != nil {
|
2023-08-24 11:06:51 +08:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Commit transaction
|
|
|
|
return committer.Commit()
|
|
|
|
}
|
|
|
|
|
|
|
|
func DeleteScheduleTaskByRepo(ctx context.Context, id int64) error {
|
|
|
|
ctx, committer, err := db.TxContext(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer committer.Close()
|
|
|
|
|
|
|
|
if _, err := db.GetEngine(ctx).Delete(&ActionSchedule{RepoID: id}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := db.GetEngine(ctx).Delete(&ActionScheduleSpec{RepoID: id}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return committer.Commit()
|
|
|
|
}
|
2024-01-13 05:50:38 +08:00
|
|
|
|
|
|
|
func CleanRepoScheduleTasks(ctx context.Context, repo *repo_model.Repository) error {
|
|
|
|
// If actions disabled when there is schedule task, this will remove the outdated schedule tasks
|
|
|
|
// There is no other place we can do this because the app.ini will be changed manually
|
|
|
|
if err := DeleteScheduleTaskByRepo(ctx, repo.ID); err != nil {
|
|
|
|
return fmt.Errorf("DeleteCronTaskByRepo: %v", err)
|
|
|
|
}
|
|
|
|
// cancel running cron jobs of this repository and delete old schedules
|
2024-03-21 15:01:35 +08:00
|
|
|
if err := CancelPreviousJobs(
|
2024-01-13 05:50:38 +08:00
|
|
|
ctx,
|
|
|
|
repo.ID,
|
|
|
|
repo.DefaultBranch,
|
|
|
|
"",
|
|
|
|
webhook_module.HookEventSchedule,
|
|
|
|
); err != nil {
|
2024-03-21 15:01:35 +08:00
|
|
|
return fmt.Errorf("CancelPreviousJobs: %v", err)
|
2024-01-13 05:50:38 +08:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|