Merge branch 'origin/main' into 'next-release/main'

This commit is contained in:
oauth 2024-09-16 19:40:25 +00:00
commit c03ce38dbe
42 changed files with 118 additions and 1396 deletions

View file

@ -33,7 +33,7 @@ import (
func runGrpcServer(ctx context.Context, c *cli.Command, _store store.Store) error { func runGrpcServer(ctx context.Context, c *cli.Command, _store store.Store) error {
lis, err := net.Listen("tcp", c.String("grpc-addr")) lis, err := net.Listen("tcp", c.String("grpc-addr"))
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("failed to listen on grpc-addr") //nolint:forbidigo return fmt.Errorf("failed to listen on grpc-addr: %w", err)
} }
jwtSecret := c.String("grpc-secret") jwtSecret := c.String("grpc-secret")

View file

@ -34,6 +34,7 @@ Some versions need some changes to the server configuration or the pipeline conf
- Replaced `configs` object by `netrc` in external configuration APIs - Replaced `configs` object by `netrc` in external configuration APIs
- Removed old API routes: `registry/` -> `registries`, `/authorize/token` - Removed old API routes: `registry/` -> `registries`, `/authorize/token`
- Replaced `registry` command with `repo registry` in cli - Replaced `registry` command with `repo registry` in cli
- Disallow upgrades from 1.x, upgrade to 2.x first
## 2.0.0 ## 2.0.0

View file

@ -26,12 +26,12 @@ import (
var addOrgID = xormigrate.Migration{ var addOrgID = xormigrate.Migration{
ID: "add-org-id", ID: "add-org-id",
MigrateSession: func(sess *xorm.Session) error { MigrateSession: func(sess *xorm.Session) error {
if err := sess.Sync(new(userV031)); err != nil { if err := sess.Sync(new(userV009)); err != nil {
return fmt.Errorf("sync new models failed: %w", err) return fmt.Errorf("sync new models failed: %w", err)
} }
// get all users // get all users
var users []*userV031 var users []*userV009
if err := sess.Find(&users); err != nil { if err := sess.Find(&users); err != nil {
return fmt.Errorf("find all repos failed: %w", err) return fmt.Errorf("find all repos failed: %w", err)
} }

View file

@ -1,150 +0,0 @@
// Copyright 2021 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"
"github.com/rs/zerolog/log"
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
)
var legacy2Xorm = xormigrate.Migration{
ID: "xorm",
MigrateSession: func(sess *xorm.Session) error {
// make sure we have required migrations - else fail and point to last major version
for _, mig := range []string{
// users
"create-table-users",
"update-table-set-users-token-and-secret-length",
// repos
"create-table-repos",
"alter-table-add-repo-visibility",
"update-table-set-repo-visibility",
"alter-table-add-repo-seq",
"update-table-set-repo-seq",
"update-table-set-repo-seq-default",
"alter-table-add-repo-active",
"update-table-set-repo-active",
"alter-table-add-repo-fallback", // needed to drop col
// builds
"create-table-builds",
"create-index-builds-repo",
"create-index-builds-author",
// procs
"create-table-procs",
"create-index-procs-build",
// files
"create-table-files",
"create-index-files-builds",
"create-index-files-procs",
"alter-table-add-file-pid",
"alter-table-add-file-meta-passed",
"alter-table-add-file-meta-failed",
"alter-table-add-file-meta-skipped",
"alter-table-update-file-meta",
// secrets
"create-table-secrets",
"create-index-secrets-repo",
// registry
"create-table-registry",
"create-index-registry-repo",
// senders
"create-table-senders",
"create-index-sender-repos",
// perms
"create-table-perms",
"create-index-perms-repo",
"create-index-perms-user",
// build_config
"create-table-build-config",
"populate-build-config",
} {
exist, err := sess.Exist(&xormigrate.Migration{ID: mig})
if err != nil {
return fmt.Errorf("test migration existence: %w", err)
}
if !exist {
log.Error().Msgf("migration step '%s' missing, please upgrade to last stable v0.14.x version first", mig)
return fmt.Errorf("legacy migration step missing")
}
}
{ // recreate build_config
type BuildConfig struct {
ConfigID int64 `xorm:"NOT NULL 'config_id'"` // xorm.Sync() do not use index info of sess -> so it tries to create it twice
BuildID int64 `xorm:"NOT NULL 'build_id'"`
}
if err := renameTable(sess, "build_config", "old_build_config"); err != nil {
return err
}
if err := sess.Sync(new(BuildConfig)); err != nil {
return err
}
if _, err := sess.Exec("INSERT INTO build_config (config_id, build_id) SELECT config_id,build_id FROM old_build_config;"); err != nil {
return fmt.Errorf("unable to set copy data into temp table %s. Error: %w", "old_build_config", err)
}
if err := sess.DropTable("old_build_config"); err != nil {
return fmt.Errorf("could not drop table '%s': %w", "old_build_config", err)
}
}
dialect := sess.Engine().Dialect().URI().DBType
switch dialect {
case schemas.MYSQL:
for _, exec := range []string{
"DROP INDEX IF EXISTS build_number ON builds;",
"DROP INDEX IF EXISTS ix_build_repo ON builds;",
"DROP INDEX IF EXISTS ix_build_author ON builds;",
"DROP INDEX IF EXISTS proc_build_ix ON procs;",
"DROP INDEX IF EXISTS file_build_ix ON files;",
"DROP INDEX IF EXISTS file_proc_ix ON files;",
"DROP INDEX IF EXISTS ix_secrets_repo ON secrets;",
"DROP INDEX IF EXISTS ix_registry_repo ON registry;",
"DROP INDEX IF EXISTS sender_repo_ix ON senders;",
"DROP INDEX IF EXISTS ix_perms_repo ON perms;",
"DROP INDEX IF EXISTS ix_perms_user ON perms;",
} {
if _, err := sess.Exec(exec); err != nil {
return fmt.Errorf("exec: '%s' failed: %w", exec, err)
}
}
case schemas.SQLITE, schemas.POSTGRES:
for _, exec := range []string{
"DROP INDEX IF EXISTS ix_build_status_running;",
"DROP INDEX IF EXISTS ix_build_repo;",
"DROP INDEX IF EXISTS ix_build_author;",
"DROP INDEX IF EXISTS proc_build_ix;",
"DROP INDEX IF EXISTS file_build_ix;",
"DROP INDEX IF EXISTS file_proc_ix;",
"DROP INDEX IF EXISTS ix_secrets_repo;",
"DROP INDEX IF EXISTS ix_registry_repo;",
"DROP INDEX IF EXISTS sender_repo_ix;",
"DROP INDEX IF EXISTS ix_perms_repo;",
"DROP INDEX IF EXISTS ix_perms_user;",
} {
if _, err := sess.Exec(exec); err != nil {
return fmt.Errorf("exec: '%s' failed: %w", exec, err)
}
}
default:
return fmt.Errorf("dialect '%s' not supported", dialect)
}
return nil
},
}

View file

@ -1,27 +0,0 @@
// Copyright 2021 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var alterTableReposDropFallback = xormigrate.Migration{
ID: "alter-table-drop-repo-fallback",
MigrateSession: func(sess *xorm.Session) error {
return dropTableColumns(sess, "repos", "repo_fallback")
},
}

View file

@ -1,30 +0,0 @@
// Copyright 2021 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var alterTableReposDropAllowDeploysAllowTags = xormigrate.Migration{
ID: "drop-allow-push-tags-deploys-columns",
MigrateSession: func(sess *xorm.Session) error {
return dropTableColumns(sess, "repos",
"repo_allow_deploys",
"repo_allow_tags",
)
},
}

View file

@ -1,51 +0,0 @@
// Copyright 2021 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
)
var fixPRSecretEventName = xormigrate.Migration{
ID: "fix-pr-secret-event-name",
MigrateSession: func(sess *xorm.Session) error {
const batchSize = 100
for start := 0; ; start += batchSize {
secrets := make([]*model.Secret, 0, batchSize)
if err := sess.Limit(batchSize, start).Table("secrets").Cols("secret_id", "secret_events").Where("secret_events LIKE '%pull-request%'").Find(&secrets); err != nil {
return err
}
if len(secrets) == 0 {
break
}
for _, secret := range secrets {
for i, event := range secret.Events {
if event == "pull-request" {
secret.Events[i] = "pull_request"
}
}
if _, err := sess.ID(secret.ID).Cols("secret_events").Update(secret); err != nil {
return err
}
}
}
return nil
},
}

View file

@ -19,7 +19,7 @@ import (
"xorm.io/xorm" "xorm.io/xorm"
) )
type oldSecret026 struct { type oldSecret004 struct {
ID int64 `json:"id" xorm:"pk autoincr 'secret_id'"` ID int64 `json:"id" xorm:"pk autoincr 'secret_id'"`
PluginsOnly bool `json:"plugins_only" xorm:"secret_plugins_only"` PluginsOnly bool `json:"plugins_only" xorm:"secret_plugins_only"`
SkipVerify bool `json:"-" xorm:"secret_skip_verify"` SkipVerify bool `json:"-" xorm:"secret_skip_verify"`
@ -27,7 +27,7 @@ type oldSecret026 struct {
Images []string `json:"images" xorm:"json 'secret_images'"` Images []string `json:"images" xorm:"json 'secret_images'"`
} }
func (oldSecret026) TableName() string { func (oldSecret004) TableName() string {
return "secrets" return "secrets"
} }
@ -35,7 +35,7 @@ var removePluginOnlyOptionFromSecretsTable = xormigrate.Migration{
ID: "remove-plugin-only-option-from-secrets-table", ID: "remove-plugin-only-option-from-secrets-table",
MigrateSession: func(sess *xorm.Session) (err error) { MigrateSession: func(sess *xorm.Session) (err error) {
// make sure plugin_only column exists // make sure plugin_only column exists
if err := sess.Sync(new(oldSecret026)); err != nil { if err := sess.Sync(new(oldSecret004)); err != nil {
return err return err
} }

View file

@ -21,20 +21,20 @@ import (
errorTypes "go.woodpecker-ci.org/woodpecker/v2/pipeline/errors/types" errorTypes "go.woodpecker-ci.org/woodpecker/v2/pipeline/errors/types"
) )
// perPage027 set the size of the slice to read per page. // perPage005 set the size of the slice to read per page.
var perPage027 = 100 var perPage005 = 100
type pipeline027 struct { type pipeline005 struct {
ID int64 `json:"id" xorm:"pk autoincr 'pipeline_id'"` ID int64 `json:"id" xorm:"pk autoincr 'pipeline_id'"`
Error string `json:"error" xorm:"LONGTEXT 'pipeline_error'"` // old error format Error string `json:"error" xorm:"LONGTEXT 'pipeline_error'"` // old error format
Errors []*errorTypes.PipelineError `json:"errors" xorm:"json 'pipeline_errors'"` // new error format Errors []*errorTypes.PipelineError `json:"errors" xorm:"json 'pipeline_errors'"` // new error format
} }
func (pipeline027) TableName() string { func (pipeline005) TableName() string {
return "pipelines" return "pipelines"
} }
type PipelineError027 struct { type PipelineError005 struct {
Type string `json:"type"` Type string `json:"type"`
Message string `json:"message"` Message string `json:"message"`
IsWarning bool `json:"is_warning"` IsWarning bool `json:"is_warning"`
@ -46,23 +46,23 @@ var convertToNewPipelineErrorFormat = xormigrate.Migration{
Long: true, Long: true,
MigrateSession: func(sess *xorm.Session) (err error) { MigrateSession: func(sess *xorm.Session) (err error) {
// make sure pipeline_error column exists // make sure pipeline_error column exists
if err := sess.Sync(new(pipeline027)); err != nil { if err := sess.Sync(new(pipeline005)); err != nil {
return err return err
} }
page := 0 page := 0
oldPipelines := make([]*pipeline027, 0, perPage027) oldPipelines := make([]*pipeline005, 0, perPage005)
for { for {
oldPipelines = oldPipelines[:0] oldPipelines = oldPipelines[:0]
err := sess.Limit(perPage027, page*perPage027).Cols("pipeline_id", "pipeline_error").Where("pipeline_error != ''").Find(&oldPipelines) err := sess.Limit(perPage005, page*perPage005).Cols("pipeline_id", "pipeline_error").Where("pipeline_error != ''").Find(&oldPipelines)
if err != nil { if err != nil {
return err return err
} }
for _, oldPipeline := range oldPipelines { for _, oldPipeline := range oldPipelines {
var newPipeline pipeline027 var newPipeline pipeline005
newPipeline.ID = oldPipeline.ID newPipeline.ID = oldPipeline.ID
newPipeline.Errors = []*errorTypes.PipelineError{{ newPipeline.Errors = []*errorTypes.PipelineError{{
Type: "generic", Type: "generic",
@ -74,7 +74,7 @@ var convertToNewPipelineErrorFormat = xormigrate.Migration{
} }
} }
if len(oldPipelines) < perPage027 { if len(oldPipelines) < perPage005 {
break break
} }

View file

@ -1,27 +0,0 @@
// Copyright 2021 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var alterTableReposDropCounter = xormigrate.Migration{
ID: "alter-table-drop-counter",
MigrateSession: func(sess *xorm.Session) error {
return dropTableColumns(sess, "repos", "repo_counter")
},
}

View file

@ -1,27 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var dropSenders = xormigrate.Migration{
ID: "drop-senders",
MigrateSession: func(sess *xorm.Session) error {
return sess.DropTable("senders")
},
}

View file

@ -19,17 +19,17 @@ import (
"xorm.io/xorm" "xorm.io/xorm"
) )
type oldRegistry029 struct { type oldRegistry007 struct {
ID int64 `json:"id" xorm:"pk autoincr 'registry_id'"` ID int64 `json:"id" xorm:"pk autoincr 'registry_id'"`
Token string `json:"token" xorm:"TEXT 'registry_token'"` Token string `json:"token" xorm:"TEXT 'registry_token'"`
Email string `json:"email" xorm:"varchar(500) 'registry_email'"` Email string `json:"email" xorm:"varchar(500) 'registry_email'"`
} }
func (oldRegistry029) TableName() string { func (oldRegistry007) TableName() string {
return "registry" return "registry"
} }
type oldPipeline029 struct { type oldPipeline007 struct {
ID int64 `json:"id" xorm:"pk autoincr 'pipeline_id'"` ID int64 `json:"id" xorm:"pk autoincr 'pipeline_id'"`
ConfigID int64 `json:"-" xorm:"pipeline_config_id"` ConfigID int64 `json:"-" xorm:"pipeline_config_id"`
Enqueued int64 `json:"enqueued_at" xorm:"pipeline_enqueued"` Enqueued int64 `json:"enqueued_at" xorm:"pipeline_enqueued"`
@ -37,14 +37,14 @@ type oldPipeline029 struct {
} }
// TableName return database table name for xorm. // TableName return database table name for xorm.
func (oldPipeline029) TableName() string { func (oldPipeline007) TableName() string {
return "pipelines" return "pipelines"
} }
var cleanRegistryPipeline = xormigrate.Migration{ var cleanRegistryPipeline = xormigrate.Migration{
ID: "clean-registry-pipeline", ID: "clean-registry-pipeline",
MigrateSession: func(sess *xorm.Session) (err error) { MigrateSession: func(sess *xorm.Session) (err error) {
if err := sess.Sync(new(oldRegistry029), new(oldPipeline029)); err != nil { if err := sess.Sync(new(oldRegistry007), new(oldPipeline007)); err != nil {
return err return err
} }

View file

@ -1,40 +0,0 @@
// Copyright 2023 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
)
var alterTableLogUpdateColumnLogDataType = xormigrate.Migration{
ID: "alter-table-logs-update-type-of-data",
MigrateSession: func(sess *xorm.Session) (err error) {
dialect := sess.Engine().Dialect().URI().DBType
switch dialect {
case schemas.POSTGRES:
_, err = sess.Exec("ALTER TABLE logs ALTER COLUMN log_data TYPE BYTEA")
case schemas.MYSQL:
_, err = sess.Exec("ALTER TABLE logs MODIFY COLUMN log_data LONGBLOB")
default:
// sqlite does only know BLOB in all cases
return nil
}
return err
},
}

View file

@ -1,47 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
type SecretV008 struct {
Owner string `json:"-" xorm:"NOT NULL DEFAULT '' UNIQUE(s) INDEX 'secret_owner'"`
RepoID int64 `json:"-" xorm:"NOT NULL DEFAULT 0 UNIQUE(s) INDEX 'secret_repo_id'"`
Name string `json:"name" xorm:"NOT NULL UNIQUE(s) INDEX 'secret_name'"`
}
// TableName return database table name for xorm.
func (SecretV008) TableName() string {
return "secrets"
}
var alterTableSecretsAddUserCol = xormigrate.Migration{
ID: "alter-table-add-secrets-user-id",
MigrateSession: func(sess *xorm.Session) error {
if err := sess.Sync(new(SecretV008)); err != nil {
return err
}
if err := alterColumnDefault(sess, "secrets", "secret_repo_id", "0"); err != nil {
return err
}
if err := alterColumnNull(sess, "secrets", "secret_repo_id", false); err != nil {
return err
}
return alterColumnNull(sess, "secrets", "secret_name", false)
},
}

View file

@ -23,7 +23,7 @@ import (
"go.woodpecker-ci.org/woodpecker/v2/server/model" "go.woodpecker-ci.org/woodpecker/v2/server/model"
) )
type userV030 struct { type userV008 struct {
ID int64 `xorm:"pk autoincr 'user_id'"` ID int64 `xorm:"pk autoincr 'user_id'"`
ForgeID int64 `xorm:"forge_id"` ForgeID int64 `xorm:"forge_id"`
ForgeRemoteID model.ForgeRemoteID `xorm:"forge_remote_id"` ForgeRemoteID model.ForgeRemoteID `xorm:"forge_remote_id"`
@ -38,11 +38,11 @@ type userV030 struct {
OrgID int64 `xorm:"user_org_id"` OrgID int64 `xorm:"user_org_id"`
} }
func (userV030) TableName() string { func (userV008) TableName() string {
return "users" return "users"
} }
type repoV030 struct { type repoV008 struct {
ID int64 `xorm:"pk autoincr 'repo_id'"` ID int64 `xorm:"pk autoincr 'repo_id'"`
UserID int64 `xorm:"repo_user_id"` UserID int64 `xorm:"repo_user_id"`
ForgeID int64 `xorm:"forge_id"` ForgeID int64 `xorm:"forge_id"`
@ -73,11 +73,11 @@ type repoV030 struct {
NetrcOnlyTrusted bool `xorm:"NOT NULL DEFAULT true 'netrc_only_trusted'"` NetrcOnlyTrusted bool `xorm:"NOT NULL DEFAULT true 'netrc_only_trusted'"`
} }
func (repoV030) TableName() string { func (repoV008) TableName() string {
return "repos" return "repos"
} }
type forgeV030 struct { type forgeV008 struct {
ID int64 `xorm:"pk autoincr 'id'"` ID int64 `xorm:"pk autoincr 'id'"`
Type model.ForgeType `xorm:"VARCHAR(250) 'type'"` Type model.ForgeType `xorm:"VARCHAR(250) 'type'"`
URL string `xorm:"VARCHAR(500) 'url'"` URL string `xorm:"VARCHAR(500) 'url'"`
@ -88,18 +88,18 @@ type forgeV030 struct {
AdditionalOptions map[string]any `xorm:"json 'additional_options'"` AdditionalOptions map[string]any `xorm:"json 'additional_options'"`
} }
func (forgeV030) TableName() string { func (forgeV008) TableName() string {
return "forge" return "forge"
} }
var setForgeID = xormigrate.Migration{ var setForgeID = xormigrate.Migration{
ID: "set-forge-id", ID: "set-forge-id",
MigrateSession: func(sess *xorm.Session) (err error) { MigrateSession: func(sess *xorm.Session) (err error) {
if err := sess.Sync(new(userV030), new(repoV030), new(forgeV030), new(model.Org)); err != nil { if err := sess.Sync(new(userV008), new(repoV008), new(forgeV008), new(model.Org)); err != nil {
return fmt.Errorf("sync new models failed: %w", err) return fmt.Errorf("sync new models failed: %w", err)
} }
_, err = sess.Exec(fmt.Sprintf("UPDATE `%s` SET forge_id=1;", userV030{}.TableName())) _, err = sess.Exec(fmt.Sprintf("UPDATE `%s` SET forge_id=1;", userV008{}.TableName()))
if err != nil { if err != nil {
return err return err
} }
@ -109,7 +109,7 @@ var setForgeID = xormigrate.Migration{
return err return err
} }
_, err = sess.Exec(fmt.Sprintf("UPDATE `%s` SET forge_id=1;", repoV030{}.TableName())) _, err = sess.Exec(fmt.Sprintf("UPDATE `%s` SET forge_id=1;", repoV008{}.TableName()))
return err return err
}, },
} }

View file

@ -1,28 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var lowercaseSecretNames = xormigrate.Migration{
ID: "lowercase-secret-names",
MigrateSession: func(sess *xorm.Session) (err error) {
_, err = sess.Exec("UPDATE secrets SET secret_name = LOWER(secret_name);")
return err
},
}

View file

@ -1,32 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
)
var recreateAgentsTable = xormigrate.Migration{
ID: "recreate-agents-table",
MigrateSession: func(sess *xorm.Session) error {
if err := sess.DropTable("agents"); err != nil {
return err
}
return sess.Sync(new(model.Agent))
},
}

View file

@ -24,7 +24,7 @@ import (
"go.woodpecker-ci.org/woodpecker/v2/server/model" "go.woodpecker-ci.org/woodpecker/v2/server/model"
) )
type configV031 struct { type configV009 struct {
ID int64 `xorm:"pk autoincr 'config_id'"` ID int64 `xorm:"pk autoincr 'config_id'"`
RepoID int64 `xorm:"UNIQUE(s) 'config_repo_id'"` RepoID int64 `xorm:"UNIQUE(s) 'config_repo_id'"`
Hash string `xorm:"UNIQUE(s) 'config_hash'"` Hash string `xorm:"UNIQUE(s) 'config_hash'"`
@ -32,11 +32,11 @@ type configV031 struct {
Data []byte `xorm:"LONGBLOB 'config_data'"` Data []byte `xorm:"LONGBLOB 'config_data'"`
} }
func (configV031) TableName() string { func (configV009) TableName() string {
return "config" return "config"
} }
type cronV031 struct { type cronV009 struct {
ID int64 `xorm:"pk autoincr 'i_d'"` ID int64 `xorm:"pk autoincr 'i_d'"`
Name string `xorm:"name UNIQUE(s) INDEX"` Name string `xorm:"name UNIQUE(s) INDEX"`
RepoID int64 `xorm:"repo_id UNIQUE(s) INDEX"` RepoID int64 `xorm:"repo_id UNIQUE(s) INDEX"`
@ -47,11 +47,11 @@ type cronV031 struct {
Branch string `xorm:"branch"` Branch string `xorm:"branch"`
} }
func (cronV031) TableName() string { func (cronV009) TableName() string {
return "crons" return "crons"
} }
type permV031 struct { type permV009 struct {
UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL 'perm_user_id'"` UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL 'perm_user_id'"`
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL 'perm_repo_id'"` RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL 'perm_repo_id'"`
Pull bool `xorm:"perm_pull"` Pull bool `xorm:"perm_pull"`
@ -60,11 +60,11 @@ type permV031 struct {
Synced int64 `xorm:"perm_synced"` Synced int64 `xorm:"perm_synced"`
} }
func (permV031) TableName() string { func (permV009) TableName() string {
return "perms" return "perms"
} }
type pipelineV031 struct { type pipelineV009 struct {
ID int64 `xorm:"pk autoincr 'pipeline_id'"` ID int64 `xorm:"pk autoincr 'pipeline_id'"`
RepoID int64 `xorm:"UNIQUE(s) INDEX 'pipeline_repo_id'"` RepoID int64 `xorm:"UNIQUE(s) INDEX 'pipeline_repo_id'"`
Number int64 `xorm:"UNIQUE(s) 'pipeline_number'"` Number int64 `xorm:"UNIQUE(s) 'pipeline_number'"`
@ -93,19 +93,19 @@ type pipelineV031 struct {
Reviewed int64 `xorm:"pipeline_reviewed"` Reviewed int64 `xorm:"pipeline_reviewed"`
} }
func (pipelineV031) TableName() string { func (pipelineV009) TableName() string {
return "pipelines" return "pipelines"
} }
type redirectionV031 struct { type redirectionV009 struct {
ID int64 `xorm:"pk autoincr 'redirection_id'"` ID int64 `xorm:"pk autoincr 'redirection_id'"`
} }
func (r redirectionV031) TableName() string { func (r redirectionV009) TableName() string {
return "redirections" return "redirections"
} }
type registryV031 struct { type registryV009 struct {
ID int64 `xorm:"pk autoincr 'registry_id'"` ID int64 `xorm:"pk autoincr 'registry_id'"`
RepoID int64 `xorm:"UNIQUE(s) INDEX 'registry_repo_id'"` RepoID int64 `xorm:"UNIQUE(s) INDEX 'registry_repo_id'"`
Address string `xorm:"UNIQUE(s) INDEX 'registry_addr'"` Address string `xorm:"UNIQUE(s) INDEX 'registry_addr'"`
@ -113,11 +113,11 @@ type registryV031 struct {
Password string `xorm:"TEXT 'registry_password'"` Password string `xorm:"TEXT 'registry_password'"`
} }
func (registryV031) TableName() string { func (registryV009) TableName() string {
return "registry" return "registry"
} }
type repoV031 struct { type repoV009 struct {
ID int64 `xorm:"pk autoincr 'repo_id'"` ID int64 `xorm:"pk autoincr 'repo_id'"`
UserID int64 `xorm:"repo_user_id"` UserID int64 `xorm:"repo_user_id"`
OrgID int64 `xorm:"repo_org_id"` OrgID int64 `xorm:"repo_org_id"`
@ -143,11 +143,11 @@ type repoV031 struct {
Hash string `xorm:"varchar(500) 'repo_hash'"` Hash string `xorm:"varchar(500) 'repo_hash'"`
} }
func (repoV031) TableName() string { func (repoV009) TableName() string {
return "repos" return "repos"
} }
type secretV031 struct { type secretV009 struct {
ID int64 `xorm:"pk autoincr 'secret_id'"` ID int64 `xorm:"pk autoincr 'secret_id'"`
OrgID int64 `xorm:"NOT NULL DEFAULT 0 UNIQUE(s) INDEX 'secret_org_id'"` OrgID int64 `xorm:"NOT NULL DEFAULT 0 UNIQUE(s) INDEX 'secret_org_id'"`
RepoID int64 `xorm:"NOT NULL DEFAULT 0 UNIQUE(s) INDEX 'secret_repo_id'"` RepoID int64 `xorm:"NOT NULL DEFAULT 0 UNIQUE(s) INDEX 'secret_repo_id'"`
@ -157,11 +157,11 @@ type secretV031 struct {
Events []model.WebhookEvent `xorm:"json 'secret_events'"` Events []model.WebhookEvent `xorm:"json 'secret_events'"`
} }
func (secretV031) TableName() string { func (secretV009) TableName() string {
return "secrets" return "secrets"
} }
type stepV031 struct { type stepV009 struct {
ID int64 `xorm:"pk autoincr 'step_id'"` ID int64 `xorm:"pk autoincr 'step_id'"`
UUID string `xorm:"INDEX 'step_uuid'"` UUID string `xorm:"INDEX 'step_uuid'"`
PipelineID int64 `xorm:"UNIQUE(s) INDEX 'step_pipeline_id'"` PipelineID int64 `xorm:"UNIQUE(s) INDEX 'step_pipeline_id'"`
@ -177,11 +177,11 @@ type stepV031 struct {
Type model.StepType `xorm:"step_type"` Type model.StepType `xorm:"step_type"`
} }
func (stepV031) TableName() string { func (stepV009) TableName() string {
return "steps" return "steps"
} }
type taskV031 struct { type taskV009 struct {
ID string `xorm:"PK UNIQUE 'task_id'"` ID string `xorm:"PK UNIQUE 'task_id'"`
Data []byte `xorm:"LONGBLOB 'task_data'"` Data []byte `xorm:"LONGBLOB 'task_data'"`
Labels map[string]string `xorm:"json 'task_labels'"` Labels map[string]string `xorm:"json 'task_labels'"`
@ -190,11 +190,11 @@ type taskV031 struct {
DepStatus map[string]model.StatusValue `xorm:"json 'task_dep_status'"` DepStatus map[string]model.StatusValue `xorm:"json 'task_dep_status'"`
} }
func (taskV031) TableName() string { func (taskV009) TableName() string {
return "tasks" return "tasks"
} }
type userV031 struct { type userV009 struct {
ID int64 `xorm:"pk autoincr 'user_id'"` ID int64 `xorm:"pk autoincr 'user_id'"`
Login string `xorm:"UNIQUE 'user_login'"` Login string `xorm:"UNIQUE 'user_login'"`
Token string `xorm:"TEXT 'user_token'"` Token string `xorm:"TEXT 'user_token'"`
@ -207,11 +207,11 @@ type userV031 struct {
OrgID int64 `xorm:"user_org_id"` OrgID int64 `xorm:"user_org_id"`
} }
func (userV031) TableName() string { func (userV009) TableName() string {
return "users" return "users"
} }
type workflowV031 struct { type workflowV009 struct {
ID int64 `xorm:"pk autoincr 'workflow_id'"` ID int64 `xorm:"pk autoincr 'workflow_id'"`
PipelineID int64 `xorm:"UNIQUE(s) INDEX 'workflow_pipeline_id'"` PipelineID int64 `xorm:"UNIQUE(s) INDEX 'workflow_pipeline_id'"`
PID int `xorm:"UNIQUE(s) 'workflow_pid'"` PID int `xorm:"UNIQUE(s) 'workflow_pid'"`
@ -226,23 +226,23 @@ type workflowV031 struct {
AxisID int `xorm:"workflow_axis_id"` AxisID int `xorm:"workflow_axis_id"`
} }
func (workflowV031) TableName() string { func (workflowV009) TableName() string {
return "workflows" return "workflows"
} }
type serverConfigV031 struct { type serverConfigV009 struct {
Key string `xorm:"pk 'key'"` Key string `xorm:"pk 'key'"`
Value string `xorm:"value"` Value string `xorm:"value"`
} }
func (serverConfigV031) TableName() string { func (serverConfigV009) TableName() string {
return "server_config" return "server_config"
} }
var unifyColumnsTables = xormigrate.Migration{ var unifyColumnsTables = xormigrate.Migration{
ID: "unify-columns-tables", ID: "unify-columns-tables",
MigrateSession: func(sess *xorm.Session) (err error) { MigrateSession: func(sess *xorm.Session) (err error) {
if err := sess.Sync(new(configV031), new(cronV031), new(permV031), new(pipelineV031), new(redirectionV031), new(registryV031), new(repoV031), new(secretV031), new(stepV031), new(taskV031), new(userV031), new(workflowV031), new(serverConfigV031)); err != nil { if err := sess.Sync(new(configV009), new(cronV009), new(permV009), new(pipelineV009), new(redirectionV009), new(registryV009), new(repoV009), new(secretV009), new(stepV009), new(taskV009), new(userV009), new(workflowV009), new(serverConfigV009)); err != nil {
return fmt.Errorf("sync models failed: %w", err) return fmt.Errorf("sync models failed: %w", err)
} }

View file

@ -1,35 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var renameBuildsToPipeline = xormigrate.Migration{
ID: "rename-builds-to-pipeline",
MigrateSession: func(sess *xorm.Session) error {
err := renameTable(sess, "builds", "pipelines")
if err != nil {
return err
}
err = renameTable(sess, "build_config", "pipeline_config")
if err != nil {
return err
}
return nil
},
}

View file

@ -1,97 +0,0 @@
// Copyright 2022 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 (
"strings"
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
type oldTable struct {
table string
columns []string
}
var renameColumnsBuildsToPipeline = xormigrate.Migration{
ID: "rename-columns-builds-to-pipeline",
MigrateSession: func(sess *xorm.Session) error {
var oldColumns []*oldTable
oldColumns = append(oldColumns, &oldTable{
table: "pipelines",
columns: []string{
"build_id",
"build_repo_id",
"build_number",
"build_author",
"build_config_id",
"build_parent",
"build_event",
"build_status",
"build_error",
"build_enqueued",
"build_created",
"build_started",
"build_finished",
"build_deploy",
"build_commit",
"build_branch",
"build_ref",
"build_refspec",
"build_remote",
"build_title",
"build_message",
"build_timestamp",
"build_sender",
"build_avatar",
"build_email",
"build_link",
"build_signed",
"build_verified",
"build_reviewer",
"build_reviewed",
},
},
)
oldColumns = append(oldColumns, &oldTable{
table: "pipeline_config",
columns: []string{"build_id"},
})
oldColumns = append(oldColumns, &oldTable{
table: "files",
columns: []string{"file_build_id"},
})
oldColumns = append(oldColumns, &oldTable{
table: "procs",
columns: []string{"proc_build_id"},
})
for _, table := range oldColumns {
for _, column := range table.columns {
err := renameColumn(sess, table.table, column, strings.Replace(column, "build_", "pipeline_", 1))
if err != nil {
return err
}
}
}
return nil
},
}

View file

@ -1,87 +0,0 @@
// Copyright 2022 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 (
"strings"
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var renameTableProcsToSteps = xormigrate.Migration{
ID: "rename-procs-to-steps",
MigrateSession: func(sess *xorm.Session) error {
err := renameTable(sess, "procs", "steps")
if err != nil {
return err
}
oldProcColumns := []*oldTable{
{
table: "steps",
columns: []string{
"proc_id",
"proc_pipeline_id",
"proc_pid",
"proc_ppid",
"proc_pgid",
"proc_name",
"proc_state",
"proc_error",
"proc_exit_code",
"proc_started",
"proc_stopped",
"proc_machine",
"proc_platform",
"proc_environ",
},
},
{
table: "files",
columns: []string{"file_proc_id"},
},
}
for _, table := range oldProcColumns {
for _, column := range table.columns {
err := renameColumn(sess, table.table, column, strings.Replace(column, "proc_", "step_", 1))
if err != nil {
return err
}
}
}
oldJobColumns := []*oldTable{
{
table: "logs",
columns: []string{
"log_job_id",
},
},
}
for _, table := range oldJobColumns {
for _, column := range table.columns {
err := renameColumn(sess, table.table, column, strings.Replace(column, "job_", "step_", 1))
if err != nil {
return err
}
}
}
return nil
},
}

View file

@ -21,26 +21,26 @@ import (
"xorm.io/xorm" "xorm.io/xorm"
) )
type stepV033 struct { type stepV012 struct {
Finished int64 `xorm:"stopped"` Finished int64 `xorm:"stopped"`
} }
func (stepV033) TableName() string { func (stepV012) TableName() string {
return "steps" return "steps"
} }
type workflowV033 struct { type workflowV012 struct {
Finished int64 `xorm:"stopped"` Finished int64 `xorm:"stopped"`
} }
func (workflowV033) TableName() string { func (workflowV012) TableName() string {
return "workflows" return "workflows"
} }
var renameStartEndTime = xormigrate.Migration{ var renameStartEndTime = xormigrate.Migration{
ID: "rename-start-end-time", ID: "rename-start-end-time",
MigrateSession: func(sess *xorm.Session) (err error) { MigrateSession: func(sess *xorm.Session) (err error) {
if err := sess.Sync(new(stepV033), new(workflowV033)); err != nil { if err := sess.Sync(new(stepV012), new(workflowV012)); err != nil {
return fmt.Errorf("sync models failed: %w", err) return fmt.Errorf("sync models failed: %w", err)
} }

View file

@ -1,45 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
type oldRepo013 struct {
ID int64 `xorm:"pk autoincr 'repo_id'"`
RemoteID string `xorm:"remote_id"`
}
func (oldRepo013) TableName() string {
return "repos"
}
var renameRemoteToForge = xormigrate.Migration{
ID: "rename-remote-to-forge",
MigrateSession: func(sess *xorm.Session) error {
if err := renameColumn(sess, "pipelines", "pipeline_remote", "pipeline_clone_url"); err != nil {
return err
}
// make sure the column exist before rename it
if err := sess.Sync(new(oldRepo013)); err != nil {
return err
}
return renameColumn(sess, "repos", "remote_id", "forge_id")
},
}

View file

@ -0,0 +1,54 @@
// 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var removeOldMigrationsOfV1 = xormigrate.Migration{
ID: "remove-old-migrations-of-v1",
MigrateSession: func(sess *xorm.Session) (err error) {
_, err = sess.Table(&xormigrate.Migration{}).In("id", []string{
"xorm",
"alter-table-drop-repo-fallback",
"drop-allow-push-tags-deploys-columns",
"fix-pr-secret-event-name",
"alter-table-drop-counter",
"drop-senders",
"alter-table-logs-update-type-of-data",
"alter-table-add-secrets-user-id",
"lowercase-secret-names",
"recreate-agents-table",
"rename-builds-to-pipeline",
"rename-columns-builds-to-pipeline",
"rename-procs-to-steps",
"rename-remote-to-forge",
"rename-forge-id-to-forge-remote-id",
"remove-active-from-users",
"remove-inactive-repos",
"drop-files",
"remove-machine-col",
"drop-old-col",
"init-log_entries",
"migrate-logs-to-log_entries",
"parent-steps-to-workflows",
"add-orgs",
}).Delete()
return err
},
}

View file

@ -1,27 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var renameForgeIDToForgeRemoteID = xormigrate.Migration{
ID: "rename-forge-id-to-forge-remote-id",
MigrateSession: func(sess *xorm.Session) error {
return renameColumn(sess, "repos", "forge_id", "forge_remote_id")
},
}

View file

@ -1,27 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var removeActiveFromUsers = xormigrate.Migration{
ID: "remove-active-from-users",
MigrateSession: func(sess *xorm.Session) error {
return dropTableColumns(sess, "users", "user_active")
},
}

View file

@ -1,33 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var removeInactiveRepos = xormigrate.Migration{
ID: "remove-inactive-repos",
MigrateSession: func(sess *xorm.Session) error {
// If the timeout is 0, the repo was never activated, so we remove it.
_, err := sess.Table("repos").Where("repo_active = ?", false).And("repo_timeout = ?", 0).Delete()
if err != nil {
return err
}
return dropTableColumns(sess, "users", "user_synced")
},
}

View file

@ -1,27 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
var dropFiles = xormigrate.Migration{
ID: "drop-files",
MigrateSession: func(sess *xorm.Session) error {
return sess.DropTable("files")
},
}

View file

@ -1,40 +0,0 @@
// Copyright 2023 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
type oldStep018 struct {
ID int64 `xorm:"pk autoincr 'step_id'"`
Machine string `xorm:"step_machine"`
}
func (oldStep018) TableName() string {
return "steps"
}
var removeMachineCol = xormigrate.Migration{
ID: "remove-machine-col",
MigrateSession: func(sess *xorm.Session) error {
// make sure step_machine column exists
if err := sess.Sync(new(oldStep018)); err != nil {
return err
}
return dropTableColumns(sess, "steps", "step_machine")
},
}

View file

@ -1,45 +0,0 @@
// Copyright 2023 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
)
type oldPipeline019 struct {
ID int64 `xorm:"pk autoincr 'pipeline_id'"`
Signed bool `xorm:"pipeline_signed"`
Verified bool `xorm:"pipeline_verified"`
}
func (oldPipeline019) TableName() string {
return "pipelines"
}
var dropOldCols = xormigrate.Migration{
ID: "drop-old-col",
MigrateSession: func(sess *xorm.Session) error {
// make sure columns on pipelines exist
if err := sess.Sync(new(oldPipeline019)); err != nil {
return err
}
if err := dropTableColumns(sess, "steps", "step_pgid"); err != nil {
return err
}
return dropTableColumns(sess, "pipelines", "pipeline_signed", "pipeline_verified")
},
}

View file

@ -1,168 +0,0 @@
// Copyright 2023 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 (
"context"
"encoding/json"
"fmt"
"runtime"
"github.com/rs/zerolog/log"
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
"go.woodpecker-ci.org/woodpecker/v2/shared/utils"
)
// perPage020 sets the size of the slice to read per page.
var perPage020 = 100
type oldLogs020 struct {
ID int64 `xorm:"pk autoincr 'log_id'"`
StepID int64 `xorm:"UNIQUE 'log_step_id'"`
Data []byte `xorm:"LONGBLOB 'log_data'"`
}
func (oldLogs020) TableName() string {
return "logs"
}
type oldLogEntry020 struct {
Step string `json:"step,omitempty"`
Time int64 `json:"time,omitempty"`
Type int `json:"type,omitempty"`
Pos int `json:"pos,omitempty"`
Out string `json:"out,omitempty"`
}
type newLogEntry020 struct {
ID int64 `xorm:"pk autoincr 'id'"`
StepID int64 `xorm:"'step_id'"`
Time int64
Line int
Data []byte `xorm:"LONGBLOB"`
Created int64 `xorm:"created"`
Type int
}
func (newLogEntry020) TableName() string {
return "log_entries"
}
var initLogsEntriesTable = xormigrate.Migration{
ID: "init-log_entries",
MigrateSession: func(sess *xorm.Session) error {
return sess.Sync(new(newLogEntry020))
},
}
var migrateLogs2LogEntries = xormigrate.Migration{
ID: "migrate-logs-to-log_entries",
Long: true,
Migrate: func(e *xorm.Engine) error {
// make sure old logs table exists
if exist, err := e.IsTableExist(new(oldLogs020)); !exist || err != nil {
return err
}
if err := e.Sync(new(oldLogs020)); err != nil {
return err
}
hasJSONErrors := false
page := 0
offset := 0
logs := make([]*oldLogs020, 0, perPage020)
logEntries := make([]*oldLogEntry020, 0, 50)
ctx, cancelCtx := context.WithCancelCause(context.Background())
defer cancelCtx(nil)
sigtermCtx := utils.WithContextSigtermCallback(ctx, func() {
log.Info().Msg("ctrl+c received, stopping current migration")
})
for {
if sigtermCtx.Err() != nil {
return fmt.Errorf("migration 'migrate-logs-to-log_entries' gracefully aborted")
}
sess := e.NewSession().NoCache()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
logs = logs[:0]
err := sess.Limit(perPage020, offset).Find(&logs)
if err != nil {
return err
}
log.Trace().Msgf("migrate-logs-to-log_entries: process page %d", page)
for _, l := range logs {
logEntries = logEntries[:0]
if err := json.Unmarshal(l.Data, &logEntries); err != nil {
hasJSONErrors = true
offset++
continue
}
time := int64(0)
for _, logEntry := range logEntries {
if logEntry.Time > time {
time = logEntry.Time
}
log := &newLogEntry020{
StepID: l.StepID,
Data: []byte(logEntry.Out),
Line: logEntry.Pos,
Time: time,
Type: logEntry.Type,
}
if _, err := sess.Insert(log); err != nil {
return err
}
}
if _, err := sess.Delete(l); err != nil {
return err
}
}
if err := sess.Commit(); err != nil {
return err
}
if len(logs) < perPage020 {
break
}
runtime.GC()
page++
}
if hasJSONErrors {
return fmt.Errorf("skipped some logs as json could not be deserialized for them")
}
return e.DropTables("logs")
},
}

View file

@ -1,87 +0,0 @@
// Copyright 2022 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 (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
)
type oldStep021 struct {
ID int64 `xorm:"pk autoincr 'step_id'"`
PipelineID int64 `xorm:"UNIQUE(s) INDEX 'step_pipeline_id'"`
PID int `xorm:"UNIQUE(s) 'step_pid'"`
PPID int `xorm:"step_ppid"`
Name string `xorm:"step_name"`
State model.StatusValue `xorm:"step_state"`
Error string `xorm:"TEXT 'step_error'"`
Started int64 `xorm:"step_started"`
Stopped int64 `xorm:"step_stopped"`
AgentID int64 `xorm:"step_agent_id"`
Platform string `xorm:"step_platform"`
Environ map[string]string `xorm:"json 'step_environ'"`
}
func (oldStep021) TableName() string {
return "steps"
}
var parentStepsToWorkflows = xormigrate.Migration{
ID: "parent-steps-to-workflows",
MigrateSession: func(sess *xorm.Session) error {
if err := sess.Sync(new(workflowV031)); err != nil {
return err
}
// make sure the columns exist before removing them
if err := sess.Sync(new(oldStep021)); err != nil {
return err
}
var parentSteps []*oldStep021
err := sess.Where("step_ppid = ?", 0).Find(&parentSteps)
if err != nil {
return err
}
for _, p := range parentSteps {
asWorkflow := &workflowV031{
PipelineID: p.PipelineID,
PID: p.PID,
Name: p.Name,
State: p.State,
Error: p.Error,
Started: p.Started,
Stopped: p.Stopped,
AgentID: p.AgentID,
Platform: p.Platform,
Environ: p.Environ,
}
_, err = sess.Insert(asWorkflow)
if err != nil {
return err
}
_, err = sess.Delete(&oldStep021{ID: p.ID})
if err != nil {
return err
}
}
return dropTableColumns(sess, "steps", "step_agent_id", "step_platform", "step_environ")
},
}

View file

@ -1,132 +0,0 @@
// Copyright 2022 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/builder"
"xorm.io/xorm"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
)
type oldSecret022 struct {
ID int64 `xorm:"pk autoincr 'secret_id'"`
Owner string `xorm:"'secret_owner'"`
OrgID int64 `xorm:"NOT NULL DEFAULT 0 'secret_org_id'"`
RepoID int64 `xorm:"NOT NULL DEFAULT 0 'secret_repo_id'"`
Name string `xorm:"NOT NULL INDEX 'secret_name'"`
}
func (oldSecret022) TableName() string {
return "secrets"
}
type syncRepo022 struct {
OrgID int64 `json:"org_id" xorm:"repo_org_id"`
}
// TableName return database table name for xorm.
func (syncRepo022) TableName() string {
return "repos"
}
type repo022 struct {
ID int64 `json:"id,omitempty" xorm:"pk autoincr 'repo_id'"`
OrgID int64 `json:"org_id" xorm:"repo_org_id"`
Owner string `json:"owner" xorm:"UNIQUE(name) 'repo_owner'"`
}
// TableName return database table name for xorm.
func (repo022) TableName() string {
return "repos"
}
var addOrgs = xormigrate.Migration{
ID: "add-orgs",
MigrateSession: func(sess *xorm.Session) error {
if exist, err := sess.IsTableExist("orgs"); exist && err == nil {
if err := sess.DropTable("orgs"); err != nil {
return fmt.Errorf("drop old orgs table failed: %w", err)
}
}
if err := sess.Sync(new(model.Org), new(syncRepo022), new(userV031)); err != nil {
return fmt.Errorf("sync new models failed: %w", err)
}
// make sure the columns exist before removing them
if _, err := sess.SyncWithOptions(xorm.SyncOptions{IgnoreConstrains: true, IgnoreIndices: true}, new(oldSecret022)); err != nil {
return fmt.Errorf("sync old secrets models failed: %w", err)
}
// get all org names from repos
var repos []*repo022
if err := sess.Find(&repos); err != nil {
return fmt.Errorf("find all repos failed: %w", err)
}
orgs := make(map[string]*model.Org)
users := make(map[string]bool)
for _, repo := range repos {
orgName := strings.ToLower(repo.Owner)
// check if it's a registered user
if _, ok := users[orgName]; !ok {
exist, err := sess.Where("user_login = ?", orgName).Exist(new(userV031))
if err != nil {
return fmt.Errorf("check if user '%s' exist failed: %w", orgName, err)
}
users[orgName] = exist
}
// create org if not already created
if _, ok := orgs[orgName]; !ok {
org := &model.Org{
Name: orgName,
IsUser: users[orgName],
}
if _, err := sess.Insert(org); err != nil {
return fmt.Errorf("insert org %#v failed: %w", org, err)
}
orgs[orgName] = org
// update org secrets
var secrets []*oldSecret022
if err := sess.Where(builder.Eq{"secret_owner": orgName, "secret_repo_id": 0}).Find(&secrets); err != nil {
return fmt.Errorf("get org secrets failed: %w", err)
}
for _, secret := range secrets {
secret.OrgID = org.ID
if _, err := sess.ID(secret.ID).Cols("secret_org_id").Update(secret); err != nil {
return fmt.Errorf("update org secret %d failed: %w", secret.ID, err)
}
}
}
// update the repo
repo.OrgID = orgs[orgName].ID
if _, err := sess.ID(repo.ID).Cols("repo_org_id").Update(repo); err != nil {
return fmt.Errorf("update repos failed: %w", err)
}
}
return dropTableColumns(sess, "secrets", "secret_owner")
},
}

View file

@ -214,7 +214,6 @@ func alterColumnDefault(sess *xorm.Session, table, column, defValue string) erro
} }
} }
//nolint:unparam
func alterColumnNull(sess *xorm.Session, table, column string, null bool) error { func alterColumnNull(sess *xorm.Session, table, column string, null bool) error {
val := "NULL" val := "NULL"
if !null { if !null {

View file

@ -29,30 +29,6 @@ import (
// They are executed in order and if one fails Xormigrate will try to rollback that specific one and quits. // They are executed in order and if one fails Xormigrate will try to rollback that specific one and quits.
var migrationTasks = []*xormigrate.Migration{ var migrationTasks = []*xormigrate.Migration{
&legacyToXormigrate, &legacyToXormigrate,
&legacy2Xorm,
&alterTableReposDropFallback,
&alterTableReposDropAllowDeploysAllowTags,
&fixPRSecretEventName,
&alterTableReposDropCounter,
&dropSenders,
&alterTableLogUpdateColumnLogDataType,
&alterTableSecretsAddUserCol,
&recreateAgentsTable,
&lowercaseSecretNames,
&renameBuildsToPipeline,
&renameColumnsBuildsToPipeline,
&renameTableProcsToSteps,
&renameRemoteToForge,
&renameForgeIDToForgeRemoteID,
&removeActiveFromUsers,
&removeInactiveRepos,
&dropFiles,
&removeMachineCol,
&dropOldCols,
&initLogsEntriesTable,
&migrateLogs2LogEntries,
&parentStepsToWorkflows,
&addOrgs,
&addOrgID, &addOrgID,
&alterTableTasksUpdateColumnTaskDataType, &alterTableTasksUpdateColumnTaskDataType,
&alterTableConfigUpdateColumnConfigDataType, &alterTableConfigUpdateColumnConfigDataType,
@ -66,6 +42,7 @@ var migrationTasks = []*xormigrate.Migration{
&cronWithoutSec, &cronWithoutSec,
&renameStartEndTime, &renameStartEndTime,
&fixV31Registries, &fixV31Registries,
&removeOldMigrationsOfV1,
} }
var allBeans = []any{ var allBeans = []any{