Migrate to maintained cron lib and remove seconds (#3785)

Co-authored-by: Patrick Schratz <patrick.schratz@gmail.com>
This commit is contained in:
qwerty287 2024-08-06 19:22:28 +02:00 committed by GitHub
parent ca41540151
commit c864f24ae4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 66 additions and 17 deletions

View file

@ -23,12 +23,6 @@ To configure cron jobs you need at least push access to the repository.
![cron settings](./cron-settings.png) ![cron settings](./cron-settings.png)
The supported schedule syntax can be found at <https://pkg.go.dev/github.com/robfig/cron?utm_source=godoc#hdr-CRON_Expression_Format>. If you need general understanding of the cron syntax <https://it-tools.tech/crontab-generator> is a good place to start and experiment. The supported schedule syntax can be found at <https://pkg.go.dev/github.com/gdgvda/cron#hdr-CRON_Expression_Format>. If you need general understanding of the cron syntax <https://it-tools.tech/crontab-generator> is a good place to start and experiment.
Examples: `@every 5m`, `@daily`, `0 30 * * * *` ... Examples: `@every 5m`, `@daily`, `30 * * * *` ...
:::info
Woodpeckers cron syntax starts with seconds instead of minutes as used by most linux cron schedulers.
Example: "At minute 30 every hour" would be `0 30 * * * *` instead of `30 * * * *`
:::

View file

@ -6,6 +6,7 @@ Some versions need some changes to the server configuration or the pipeline conf
## 3.0.0 ## 3.0.0
- Update all webhooks by pressing the "Repair all" button in the admin settings as the webhook token claims have changed - Update all webhooks by pressing the "Repair all" button in the admin settings as the webhook token claims have changed
- Crons now use standard Linux syntax without seconds
--> -->

2
go.mod
View file

@ -26,6 +26,7 @@ require (
github.com/expr-lang/expr v1.16.9 github.com/expr-lang/expr v1.16.9
github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf
github.com/fsnotify/fsnotify v1.7.0 github.com/fsnotify/fsnotify v1.7.0
github.com/gdgvda/cron v0.2.0
github.com/getkin/kin-openapi v0.126.0 github.com/getkin/kin-openapi v0.126.0
github.com/gin-gonic/gin v1.10.0 github.com/gin-gonic/gin v1.10.0
github.com/gitsight/go-vcsurl v1.0.1 github.com/gitsight/go-vcsurl v1.0.1
@ -49,7 +50,6 @@ require (
github.com/oklog/ulid/v2 v2.1.0 github.com/oklog/ulid/v2 v2.1.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.19.1 github.com/prometheus/client_golang v1.19.1
github.com/robfig/cron v1.2.0
github.com/rs/zerolog v1.33.0 github.com/rs/zerolog v1.33.0
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
github.com/swaggo/files v1.0.1 github.com/swaggo/files v1.0.1

4
go.sum
View file

@ -145,6 +145,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gdgvda/cron v0.2.0 h1:oX8qdLZq4tC5StnCsZsTNs2BIzaRjcjmPZ4o+BArKX4=
github.com/gdgvda/cron v0.2.0/go.mod h1:VEwidZXB255kESB5DcUGRWTYZS8KkOBYD1YBn8Wiyx8=
github.com/getkin/kin-openapi v0.126.0 h1:c2cSgLnAsS0xYfKsgt5oBV6MYRM/giU8/RtwUY4wyfY= github.com/getkin/kin-openapi v0.126.0 h1:c2cSgLnAsS0xYfKsgt5oBV6MYRM/giU8/RtwUY4wyfY=
github.com/getkin/kin-openapi v0.126.0/go.mod h1:7mONz8IwmSRg6RttPu6v8U/OJ+gr+J99qSFNjPGSQqw= github.com/getkin/kin-openapi v0.126.0/go.mod h1:7mONz8IwmSRg6RttPu6v8U/OJ+gr+J99qSFNjPGSQqw=
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
@ -459,8 +461,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qq
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=

View file

@ -19,7 +19,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/robfig/cron" "github.com/gdgvda/cron"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"go.woodpecker-ci.org/woodpecker/v2/server" "go.woodpecker-ci.org/woodpecker/v2/server"
@ -31,7 +31,7 @@ import (
const ( const (
// Specifies the interval woodpecker checks for new crons to exec. // Specifies the interval woodpecker checks for new crons to exec.
checkTime = 10 * time.Second checkTime = time.Minute
// Specifies the batch size of crons to retrieve per check from database. // Specifies the batch size of crons to retrieve per check from database.
checkItems = 10 checkItems = 10
@ -71,7 +71,7 @@ func CalcNewNext(schedule string, now time.Time) (time.Time, error) {
// TODO: allow the users / the admin to set a specific timezone // TODO: allow the users / the admin to set a specific timezone
c, err := cron.Parse(schedule) c, err := cron.ParseStandard(schedule)
if err != nil { if err != nil {
return time.Time{}, fmt.Errorf("cron parse schedule: %w", err) return time.Time{}, fmt.Errorf("cron parse schedule: %w", err)
} }

View file

@ -17,7 +17,7 @@ package model
import ( import (
"fmt" "fmt"
"github.com/robfig/cron" "github.com/gdgvda/cron"
) )
type Cron struct { type Cron struct {
@ -46,7 +46,7 @@ func (c *Cron) Validate() error {
return fmt.Errorf("schedule is required") return fmt.Errorf("schedule is required")
} }
_, err := cron.Parse(c.Schedule) _, err := cron.ParseStandard(c.Schedule)
if err != nil { if err != nil {
return fmt.Errorf("can't parse schedule: %w", err) return fmt.Errorf("can't parse schedule: %w", err)
} }

View file

@ -0,0 +1,53 @@
// Copyright 2024 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package migration
import (
"fmt"
"strings"
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
)
var cronWithoutSec = xormigrate.Migration{
ID: "cron-without-sec",
MigrateSession: func(sess *xorm.Session) error {
if err := sess.Sync(new(model.Cron)); err != nil {
return fmt.Errorf("sync new models failed: %w", err)
}
var crons []*model.Cron
if err := sess.Find(&crons); err != nil {
return err
}
for _, c := range crons {
if strings.HasPrefix(strings.TrimSpace(c.Schedule), "@") {
// something like "@daily"
continue
}
c.Schedule = strings.SplitN(strings.TrimSpace(c.Schedule), " ", 2)[1]
if _, err := sess.Update(c); err != nil {
return err
}
}
return nil
},
}

View file

@ -63,6 +63,7 @@ var migrationTasks = []*xormigrate.Migration{
&setForgeID, &setForgeID,
&unifyColumnsTables, &unifyColumnsTables,
&alterTableRegistriesFixRequiredFields, &alterTableRegistriesFixRequiredFields,
&cronWithoutSec,
} }
var allBeans = []any{ var allBeans = []any{

View file

@ -60,7 +60,7 @@
<InputField <InputField
v-slot="{ id }" v-slot="{ id }"
:label="$t('repo.settings.crons.schedule.title')" :label="$t('repo.settings.crons.schedule.title')"
docs-url="https://pkg.go.dev/github.com/robfig/cron?utm_source=godoc#hdr-CRON_Expression_Format" docs-url="https://pkg.go.dev/github.com/gdgvda/cron#hdr-CRON_Expression_Format"
> >
<TextField <TextField
:id="id" :id="id"