snapshot of https://github.com/go-gitea/gitea.git (main, 2026-09-15; blobs > 131072B omitted)
Some checks failed
cache-seeder / prune (push) Has been skipped
cache-seeder / frontend (push) Failing after 3s
cache-seeder / python (push) Failing after 3s
cache-seeder / gobuild (push) Failing after 4s
cache-seeder / lint (bindata, lint-backend) (push) Failing after 3s
giteabot backport / giteabot (push) Has been skipped
giteabot / giteabot (push) Has been skipped
cache-prune / prune (push) Has been skipped
release-nightly-snapcraft / build-and-publish (ubuntu-24.04) (push) Has been cancelled
release-nightly-snapcraft / build-and-publish (ubuntu-24.04-arm) (push) Has been cancelled
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled
cron-renovate / cron-renovate (push) Has been skipped
Some checks failed
cache-seeder / prune (push) Has been skipped
cache-seeder / frontend (push) Failing after 3s
cache-seeder / python (push) Failing after 3s
cache-seeder / gobuild (push) Failing after 4s
cache-seeder / lint (bindata, lint-backend) (push) Failing after 3s
giteabot backport / giteabot (push) Has been skipped
giteabot / giteabot (push) Has been skipped
cache-prune / prune (push) Has been skipped
release-nightly-snapcraft / build-and-publish (ubuntu-24.04) (push) Has been cancelled
release-nightly-snapcraft / build-and-publish (ubuntu-24.04-arm) (push) Has been cancelled
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled
cron-renovate / cron-renovate (push) Has been skipped
This commit is contained in:
14
modelmigration/v28/main_test.go
Normal file
14
modelmigration/v28/main_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modelmigration/migrationtest"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
migrationtest.MainTest(m)
|
||||
}
|
||||
24
modelmigration/v28/v343.go
Normal file
24
modelmigration/v28/v343.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddMaxParallelToActionRunJob(_ context.Context, x base.EngineMigration) error {
|
||||
type ActionRunJob struct {
|
||||
MaxParallel int `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
_, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreConstrains: true,
|
||||
IgnoreDropIndices: true,
|
||||
}, new(ActionRunJob))
|
||||
return err
|
||||
}
|
||||
37
modelmigration/v28/v343_test.go
Normal file
37
modelmigration/v28/v343_test.go
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modelmigration/migrationtest"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAddMaxParallelToActionRunJob(t *testing.T) {
|
||||
type ActionRunJob struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Name string `xorm:"VARCHAR(255)"`
|
||||
}
|
||||
|
||||
x, deferable := migrationtest.PrepareTestEnv(t, 0, new(ActionRunJob))
|
||||
defer deferable()
|
||||
if x == nil || t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
_, err := x.Insert(&ActionRunJob{Name: "job-a"})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, AddMaxParallelToActionRunJob(t.Context(), x))
|
||||
|
||||
// pre-existing rows must default to unlimited
|
||||
var maxParallel int
|
||||
has, err := x.SQL("SELECT max_parallel FROM action_run_job WHERE id = ?", 1).Get(&maxParallel)
|
||||
require.NoError(t, err)
|
||||
require.True(t, has)
|
||||
require.Equal(t, 0, maxParallel)
|
||||
}
|
||||
27
modelmigration/v28/v344.go
Normal file
27
modelmigration/v28/v344.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// AddDeferredMatrixColumnsToActionRunJob adds the columns backing deferred (dynamic) matrix expansion
|
||||
func AddDeferredMatrixColumnsToActionRunJob(_ context.Context, x base.EngineMigration) error {
|
||||
type ActionRunJob struct {
|
||||
// IsMatrixDeferred marks jobs whose matrix depends on other jobs' outputs and is therefore expanded only once those jobs finish;
|
||||
IsMatrixDeferred bool `xorm:"NOT NULL DEFAULT FALSE"`
|
||||
// DeferredMatrixPayload preserves the raw, unevaluated payload across expansion so a rerun can re-derive the matrix
|
||||
DeferredMatrixPayload []byte `xorm:"LONGBLOB"`
|
||||
}
|
||||
_, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreDropIndices: true,
|
||||
IgnoreConstrains: true,
|
||||
}, new(ActionRunJob))
|
||||
return err
|
||||
}
|
||||
25
modelmigration/v28/v345.go
Normal file
25
modelmigration/v28/v345.go
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// AddBlockOnCodeownerReviews adds block on codeowner reviews branch protection
|
||||
func AddBlockOnCodeownerReviews(_ context.Context, x base.EngineMigration) error {
|
||||
type ProtectedBranch struct {
|
||||
BlockOnCodeownerReviews bool `xorm:"NOT NULL DEFAULT false"`
|
||||
}
|
||||
|
||||
_, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreConstrains: true,
|
||||
IgnoreDropIndices: true,
|
||||
}, new(ProtectedBranch))
|
||||
return err
|
||||
}
|
||||
52
modelmigration/v28/v346.go
Normal file
52
modelmigration/v28/v346.go
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
func AddLicensePathToRepoLicense(ctx context.Context, x base.EngineMigration) error {
|
||||
// Drop the old 2-column UNIQUE(s) index on (repo_id, license) and, on
|
||||
// re-runs, the index created under the new name.
|
||||
// xorm Sync cannot reliably update an index when its column set changes.
|
||||
indexes, err := x.Dialect().GetIndexes(x.DB(), ctx, "repo_license")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, idx := range indexes {
|
||||
if idx.Name == "s" || idx.Name == "path" {
|
||||
if _, err := x.Exec(x.Dialect().DropIndexSQL("repo_license", idx)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add license_path column. The DEFAULT backfills existing rows: all repos
|
||||
// created before this migration used the single LICENSE file convention.
|
||||
type RepoLicense struct {
|
||||
LicensePath string `xorm:"VARCHAR(255) NOT NULL DEFAULT 'LICENSE'"`
|
||||
}
|
||||
if _, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreDropIndices: true,
|
||||
IgnoreConstrains: true,
|
||||
}, new(RepoLicense)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create new 3-column UNIQUE(path) index on (repo_id, license, license_path);
|
||||
// xorm prefixes the name to UQE_repo_license_path.
|
||||
newIndex := schemas.NewIndex("path", schemas.UniqueType)
|
||||
newIndex.AddColumn("repo_id", "license", "license_path")
|
||||
if _, err := x.Exec(x.Dialect().CreateIndexSQL("repo_license", newIndex)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
80
modelmigration/v28/v346_test.go
Normal file
80
modelmigration/v28/v346_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modelmigration/migrationtest"
|
||||
"gitea.dev/modules/timeutil"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
// repoLicenseBeforeV345 mirrors the pre-migration repo_license table: no
|
||||
// license_path column and a 2-column UNIQUE(s) index on (repo_id, license).
|
||||
type repoLicenseBeforeV345 struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"UNIQUE(s) NOT NULL"`
|
||||
CommitID string
|
||||
License string `xorm:"VARCHAR(255) UNIQUE(s) NOT NULL"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
|
||||
}
|
||||
|
||||
func (repoLicenseBeforeV345) TableName() string { return "repo_license" }
|
||||
|
||||
func Test_AddLicensePathToRepoLicense(t *testing.T) {
|
||||
x, deferable := migrationtest.PrepareTestEnv(t, 0, new(repoLicenseBeforeV345))
|
||||
defer deferable()
|
||||
|
||||
_, err := x.Insert(&repoLicenseBeforeV345{RepoID: 1, CommitID: "c1", License: "MIT"})
|
||||
require.NoError(t, err)
|
||||
_, err = x.Insert(&repoLicenseBeforeV345{RepoID: 1, CommitID: "c1", License: "Apache-2.0"})
|
||||
require.NoError(t, err)
|
||||
_, err = x.Insert(&repoLicenseBeforeV345{RepoID: 2, CommitID: "c2", License: "MIT"})
|
||||
require.NoError(t, err)
|
||||
|
||||
indexes, err := x.Dialect().GetIndexes(x.DB(), context.Background(), "repo_license")
|
||||
require.NoError(t, err)
|
||||
oldIdx, ok := indexes["s"] // GetIndexes strips the UQE_repo_license_ prefix
|
||||
require.True(t, ok, "old 2-column unique s index should exist before migration")
|
||||
assert.Equal(t, schemas.UniqueType, oldIdx.Type)
|
||||
assert.Equal(t, []string{"repo_id", "license"}, oldIdx.Cols)
|
||||
|
||||
require.NoError(t, AddLicensePathToRepoLicense(t.Context(), x))
|
||||
require.NoError(t, AddLicensePathToRepoLicense(t.Context(), x)) // idempotent
|
||||
|
||||
indexes, err = x.Dialect().GetIndexes(x.DB(), context.Background(), "repo_license")
|
||||
require.NoError(t, err)
|
||||
assert.NotContains(t, indexes, "s", "old 2-column unique s index should be gone after migration")
|
||||
newIdx, ok := indexes["path"] // GetIndexes strips the UQE_repo_license_ prefix
|
||||
require.True(t, ok, "new index must be named path (UQE_repo_license_path)")
|
||||
assert.Equal(t, schemas.UniqueType, newIdx.Type)
|
||||
assert.Equal(t, []string{"repo_id", "license", "license_path"}, newIdx.Cols)
|
||||
|
||||
// pre-existing rows must default to the LICENSE path
|
||||
type licenseRow struct {
|
||||
RepoID int64
|
||||
License string
|
||||
LicensePath string
|
||||
}
|
||||
var rows []licenseRow
|
||||
require.NoError(t, x.SQL("SELECT repo_id, license, license_path FROM repo_license ORDER BY id").Find(&rows))
|
||||
require.Len(t, rows, 3)
|
||||
for _, r := range rows {
|
||||
assert.Equal(t, "LICENSE", r.LicensePath)
|
||||
}
|
||||
|
||||
// the new index is unique per (repo_id, license, license_path): the exact
|
||||
// duplicate must be rejected, while a second path for the same license
|
||||
// in the same repo is allowed
|
||||
_, err = x.Exec("INSERT INTO repo_license (repo_id, commit_id, license, license_path) VALUES (1, 'c1', 'MIT', 'LICENSE')")
|
||||
require.Error(t, err)
|
||||
_, err = x.Exec("INSERT INTO repo_license (repo_id, commit_id, license, license_path) VALUES (1, 'c1', 'MIT', 'LICENSES/MIT.txt')")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
25
modelmigration/v28/v347.go
Normal file
25
modelmigration/v28/v347.go
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddWatchOptions(_ context.Context, x base.EngineMigration) error {
|
||||
type Watch struct {
|
||||
IncludePullRequests bool `xorm:"NOT NULL DEFAULT true"`
|
||||
IncludeIssues bool `xorm:"NOT NULL DEFAULT true"`
|
||||
IncludeReleases bool `xorm:"NOT NULL DEFAULT true"`
|
||||
}
|
||||
_, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreConstrains: true,
|
||||
IgnoreIndices: true,
|
||||
}, new(Watch))
|
||||
return err
|
||||
}
|
||||
24
modelmigration/v28/v348.go
Normal file
24
modelmigration/v28/v348.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
)
|
||||
|
||||
func RecreateEmailHashTable(_ context.Context, x base.EngineMigration) error {
|
||||
// the rows are unreachable MD5 hashes and their UNIQUE email index would reject the SHA256 replacements
|
||||
if err := x.DropTables("email_hash"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type EmailHash struct {
|
||||
Hash string `xorm:"pk varchar(64)"`
|
||||
Email string `xorm:"UNIQUE(email_hashtype) NOT NULL"`
|
||||
HashType string `xorm:"UNIQUE(email_hashtype) NOT NULL varchar(16)"`
|
||||
}
|
||||
return x.Sync(new(EmailHash))
|
||||
}
|
||||
38
modelmigration/v28/v348_test.go
Normal file
38
modelmigration/v28/v348_test.go
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modelmigration/migrationtest"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRecreateEmailHashTable(t *testing.T) {
|
||||
type EmailHash struct {
|
||||
Hash string `xorm:"pk varchar(32)"`
|
||||
Email string `xorm:"UNIQUE NOT NULL"`
|
||||
}
|
||||
|
||||
x, deferable := migrationtest.PrepareTestEnv(t, 0, new(EmailHash))
|
||||
defer deferable()
|
||||
if x == nil || t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
_, err := x.Insert(&EmailHash{Hash: strings.Repeat("a", 32), Email: "gitea@example.com"})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, RecreateEmailHashTable(t.Context(), x))
|
||||
|
||||
count, err := x.Count(new(EmailHash))
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, 0, count, "the unreachable MD5 rows must be gone")
|
||||
|
||||
_, err = x.Exec("INSERT INTO email_hash (hash, email, hash_type) VALUES (?, ?, ?)", strings.Repeat("b", 64), "gitea@example.com", "sha256")
|
||||
require.NoError(t, err, "the new schema must hold a SHA256 hash")
|
||||
}
|
||||
29
modelmigration/v28/v349.go
Normal file
29
modelmigration/v28/v349.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
"gitea.dev/modules/setting"
|
||||
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
func ExpandActionScheduleContent(ctx context.Context, x base.EngineMigration) error {
|
||||
if !setting.Database.Type.IsMySQL() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return base.ModifyColumn(ctx, x, "action_schedule", &schemas.Column{
|
||||
Name: "content",
|
||||
SQLType: schemas.SQLType{
|
||||
Name: "LONGBLOB",
|
||||
},
|
||||
Length: 0,
|
||||
Nullable: true,
|
||||
DefaultIsEmpty: true,
|
||||
})
|
||||
}
|
||||
47
modelmigration/v28/v349_test.go
Normal file
47
modelmigration/v28/v349_test.go
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modelmigration/migrationtest"
|
||||
"gitea.dev/modules/setting"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestExpandActionScheduleContent(t *testing.T) {
|
||||
if !setting.Database.Type.IsMySQL() {
|
||||
t.Skip("Only MySQL limits BLOB columns to 65,535 bytes")
|
||||
}
|
||||
|
||||
type ActionSchedule struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Content []byte `xorm:"BLOB"`
|
||||
}
|
||||
|
||||
x, deferable := migrationtest.PrepareTestEnv(t, 0, new(ActionSchedule))
|
||||
defer deferable()
|
||||
if x == nil || t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, ExpandActionScheduleContent(t.Context(), x))
|
||||
|
||||
tables := migrationtest.LoadTableSchemasMap(t, x)
|
||||
assert.Equal(t, "LONGBLOB", tables["action_schedule"].GetColumn("content").SQLType.Name)
|
||||
|
||||
content := bytes.Repeat([]byte("x"), 65_536)
|
||||
_, err := x.Insert(&ActionSchedule{Content: content})
|
||||
require.NoError(t, err)
|
||||
|
||||
var stored ActionSchedule
|
||||
has, err := x.Get(&stored)
|
||||
require.NoError(t, err)
|
||||
require.True(t, has)
|
||||
assert.Equal(t, content, stored.Content)
|
||||
}
|
||||
28
modelmigration/v28/v350.go
Normal file
28
modelmigration/v28/v350.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddPublishedUnixToRelease(_ context.Context, x base.EngineMigration) error {
|
||||
type Release struct {
|
||||
PublishedUnix int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
if _, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreConstrains: true,
|
||||
IgnoreDropIndices: true,
|
||||
}, new(Release)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// existing rows have no recorded publication time, so fall back to their creation time
|
||||
_, err := x.Exec("UPDATE `release` SET published_unix = created_unix WHERE published_unix = 0 AND is_draft = ?", false)
|
||||
return err
|
||||
}
|
||||
41
modelmigration/v28/v350_test.go
Normal file
41
modelmigration/v28/v350_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modelmigration/migrationtest"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAddPublishedUnixToRelease(t *testing.T) {
|
||||
type Release struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
IsDraft bool `xorm:"NOT NULL DEFAULT false"`
|
||||
IsTag bool `xorm:"NOT NULL DEFAULT false"`
|
||||
CreatedUnix int64 `xorm:"INDEX"`
|
||||
}
|
||||
|
||||
x, deferable := migrationtest.PrepareTestEnv(t, 0, new(Release))
|
||||
defer deferable()
|
||||
if x == nil || t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
_, err := x.Insert(
|
||||
&Release{CreatedUnix: 1000000},
|
||||
&Release{IsDraft: true, CreatedUnix: 2000000},
|
||||
&Release{IsTag: true, CreatedUnix: 3000000},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, AddPublishedUnixToRelease(t.Context(), x))
|
||||
|
||||
var got []struct{ PublishedUnix int64 }
|
||||
require.NoError(t, x.Table("release").OrderBy("id").Find(&got))
|
||||
require.Equal(t, []int64{1000000, 0, 3000000}, []int64{got[0].PublishedUnix, got[1].PublishedUnix, got[2].PublishedUnix},
|
||||
"everything but drafts is backfilled")
|
||||
}
|
||||
23
modelmigration/v28/v351.go
Normal file
23
modelmigration/v28/v351.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddRecipientAccessGrantedToRepoTransfer(_ context.Context, x base.EngineMigration) error {
|
||||
type RepoTransfer struct {
|
||||
RecipientAccessGranted bool `xorm:"NOT NULL DEFAULT false"`
|
||||
}
|
||||
_, err := x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreConstrains: true,
|
||||
IgnoreDropIndices: true,
|
||||
}, new(RepoTransfer))
|
||||
return err
|
||||
}
|
||||
38
modelmigration/v28/v352.go
Normal file
38
modelmigration/v28/v352.go
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddTokenToDeployKey(ctx context.Context, x base.EngineMigration) error {
|
||||
// Drop the old UNIQUE(s) index on (key_id, repo_id). Every token row carries key
|
||||
// id 0, so the pair can no longer be unique. AddDeployKey still checks it in code.
|
||||
indexes, err := x.Dialect().GetIndexes(x.DB(), ctx, "deploy_key")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if idx, ok := indexes["s"]; ok {
|
||||
if _, err := x.Exec(x.Dialect().DropIndexSQL("deploy_key", idx)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
type DeployKey struct {
|
||||
KeyID int64 `xorm:"INDEX"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
KeyType int `xorm:"NOT NULL DEFAULT 1"` // every existing row is an SSH key
|
||||
TokenHash string `xorm:"INDEX"`
|
||||
}
|
||||
_, err = x.SyncWithOptions(xorm.SyncOptions{
|
||||
IgnoreConstrains: true,
|
||||
IgnoreDropIndices: true, // the bean only describes the new columns
|
||||
}, new(DeployKey))
|
||||
return err
|
||||
}
|
||||
37
modelmigration/v28/v353.go
Normal file
37
modelmigration/v28/v353.go
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.dev/modelmigration/base"
|
||||
"gitea.dev/modules/timeutil"
|
||||
)
|
||||
|
||||
type AuditEvent struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Action string `xorm:"INDEX NOT NULL"`
|
||||
ActorID int64 `xorm:"INDEX NOT NULL"`
|
||||
ActorName string
|
||||
ActorCredential string
|
||||
ImpersonatorID int64 `xorm:"INDEX"`
|
||||
ImpersonatorName string
|
||||
ScopeID int64 `xorm:"INDEX(scope) NOT NULL"`
|
||||
ScopeType string `xorm:"INDEX INDEX(scope) NOT NULL"`
|
||||
ScopeName string
|
||||
Origin string `xorm:"INDEX NOT NULL"`
|
||||
Message string
|
||||
Metadata string `xorm:"LONGTEXT JSON"`
|
||||
IPAddress string
|
||||
TimestampUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL"`
|
||||
}
|
||||
|
||||
func (*AuditEvent) TableName() string {
|
||||
return "audit_event"
|
||||
}
|
||||
|
||||
func AddAuditEventTable(_ context.Context, x base.EngineMigration) error {
|
||||
return x.Sync(new(AuditEvent))
|
||||
}
|
||||
48
modelmigration/v28/v353_test.go
Normal file
48
modelmigration/v28/v353_test.go
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v28
|
||||
|
||||
import (
|
||||
"context"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modelmigration/migrationtest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
func TestAddAuditEventTable(t *testing.T) {
|
||||
x, deferable := migrationtest.PrepareTestEnv(t, 0)
|
||||
defer deferable()
|
||||
if x == nil || t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, AddAuditEventTable(t.Context(), x))
|
||||
|
||||
indexes, err := x.Dialect().GetIndexes(x.DB(), context.Background(), "audit_event")
|
||||
require.NoError(t, err)
|
||||
for _, columns := range [][]string{
|
||||
{"action"},
|
||||
{"actor_id"},
|
||||
{"scope_id", "scope_type"},
|
||||
{"scope_type"},
|
||||
{"origin"},
|
||||
{"timestamp_unix"},
|
||||
} {
|
||||
assert.True(t, hasAuditIndexWithColumns(indexes, columns), "missing index on %v", columns)
|
||||
}
|
||||
}
|
||||
|
||||
func hasAuditIndexWithColumns(indexes map[string]*schemas.Index, columns []string) bool {
|
||||
for _, index := range indexes {
|
||||
if slices.Equal(index.Cols, columns) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user