// 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" "reflect" "src.techknowlogick.com/xormigrate" "xorm.io/xorm" "go.woodpecker-ci.org/woodpecker/v2/server/model" ) // APPEND NEW MIGRATIONS // they are executed in order and if one fails Xormigrate will try to rollback that specific one and quits var migrationTasks = []*xormigrate.Migration{ &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, &alterTableTasksUpdateColumnTaskDataType, &alterTableConfigUpdateColumnConfigDataType, &removePluginOnlyOptionFromSecretsTable, &convertToNewPipelineErrorFormat, &renameLinkToURL, } var allBeans = []any{ new(model.Agent), new(model.Pipeline), new(model.PipelineConfig), new(model.Config), new(model.LogEntry), new(model.Perm), new(model.Step), new(model.Registry), new(model.Repo), new(model.Secret), new(model.Task), new(model.User), new(model.ServerConfig), new(model.Cron), new(model.Redirection), new(model.Workflow), new(model.Org), } func Migrate(e *xorm.Engine, allowLong bool) error { e.SetDisableGlobalCache(true) m := xormigrate.New(e, migrationTasks) m.AllowLong(allowLong) oldCount, err := e.Table("migrations").Count() if oldCount < 1 || err != nil { // allow new schema initialization if old migrations table is empty or it does not exist (err != nil) // schema initialization will always run if we call `InitSchema` m.InitSchema(func(engine *xorm.Engine) error { // do nothing on schema init, models are synced in any case below return nil }) } m.SetLogger(&xormigrateLogger{}) if err := m.Migrate(); err != nil { return err } e.SetDisableGlobalCache(false) if err := syncAll(e); err != nil { return fmt.Errorf("msg: %w", err) } return nil } func syncAll(sess *xorm.Engine) error { for _, bean := range allBeans { if err := sess.Sync(bean); err != nil { return fmt.Errorf("Sync error '%s': %w", reflect.TypeOf(bean), err) } } return nil }