diff --git a/.deadcode-out b/.deadcode-out
index 61c5bcb055..f9bee43043 100644
--- a/.deadcode-out
+++ b/.deadcode-out
@@ -27,15 +27,13 @@ forgejo.org/models/db
TruncateBeans
InTransaction
DumpTables
+ GetTableNames
forgejo.org/models/dbfs
file.renameTo
Create
Rename
-forgejo.org/models/forgefed
- GetFederationHost
-
forgejo.org/models/forgejo/semver
GetVersion
SetVersionString
@@ -67,7 +65,6 @@ forgejo.org/models/user
DeleteUserSetting
GetFederatedUser
GetFederatedUserByUserID
- UpdateFederatedUser
GetFollowersForUser
AddFollower
RemoveFollower
@@ -248,6 +245,9 @@ forgejo.org/routers/web/org
forgejo.org/services/context
GetPrivateContext
+forgejo.org/services/federation
+ Init
+
forgejo.org/services/repository
IsErrForkAlreadyExist
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 28fa9e4555..3f250e5682 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -6,7 +6,7 @@
"ghcr.io/devcontainers/features/node:1": {
"version": "22"
},
- "ghcr.io/devcontainers/features/git-lfs:1.2.4": {},
+ "ghcr.io/devcontainers/features/git-lfs:1.2.5": {},
"ghcr.io/warrenbuckley/codespace-features/sqlite:1": {}
},
"customizations": {
diff --git a/.forgejo/workflows/renovate.yml b/.forgejo/workflows/renovate.yml
index 729cba3723..d3eac5357a 100644
--- a/.forgejo/workflows/renovate.yml
+++ b/.forgejo/workflows/renovate.yml
@@ -28,7 +28,7 @@ jobs:
runs-on: docker
container:
- image: data.forgejo.org/renovate/renovate:41.17.2
+ image: data.forgejo.org/renovate/renovate:41.23.2
steps:
- name: Load renovate repo cache
diff --git a/.golangci.yml b/.golangci.yml
index 532132838d..6679a1850e 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -79,6 +79,10 @@ linters:
- name: unreachable-code
- name: var-declaration
- name: var-naming
+ arguments:
+ - []
+ - []
+ - - skip-package-name-checks: true
- name: redefines-builtin-id
disabled: true
staticcheck:
diff --git a/Makefile b/Makefile
index db4ec2fbd5..c09e0180eb 100644
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,7 @@ XGO_VERSION := go-1.21.x
AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.3.0 # renovate: datasource=go
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.8.0 # renovate: datasource=go
-GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 # renovate: datasource=go
+GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.2.1 # renovate: datasource=go
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 # renovate: datasource=go
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0 # renovate: datasource=go
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
@@ -47,7 +47,7 @@ GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasour
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go
DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.34.0 # renovate: datasource=go
GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.5.2 # renovate: datasource=go
-RENOVATE_NPM_PACKAGE ?= renovate@41.17.2 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate
+RENOVATE_NPM_PACKAGE ?= renovate@41.23.2 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate
# https://github.com/disposable-email-domains/disposable-email-domains/commits/main/
DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ...
diff --git a/cmd/admin_auth.go b/cmd/admin_auth.go
index cb95b3b3c8..91b344b1e9 100644
--- a/cmd/admin_auth.go
+++ b/cmd/admin_auth.go
@@ -17,6 +17,15 @@ import (
"github.com/urfave/cli/v3"
)
+type (
+ authService struct {
+ initDB func(ctx context.Context) error
+ createAuthSource func(context.Context, *auth_model.Source) error
+ updateAuthSource func(context.Context, *auth_model.Source) error
+ getAuthSourceByID func(ctx context.Context, id int64) (*auth_model.Source, error)
+ }
+)
+
func microcmdAuthDelete() *cli.Command {
return &cli.Command{
Name: "delete",
@@ -60,6 +69,16 @@ func microcmdAuthList() *cli.Command {
}
}
+// newAuthService creates a service with default functions.
+func newAuthService() *authService {
+ return &authService{
+ initDB: initDB,
+ createAuthSource: auth_model.CreateSource,
+ updateAuthSource: auth_model.UpdateSource,
+ getAuthSourceByID: auth_model.GetSourceByID,
+ }
+}
+
func runListAuth(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
defer cancel()
diff --git a/cmd/admin_auth_ldap.go b/cmd/admin_auth_ldap.go
index 997d6b3a16..9af6c331d3 100644
--- a/cmd/admin_auth_ldap.go
+++ b/cmd/admin_auth_ldap.go
@@ -14,15 +14,6 @@ import (
"github.com/urfave/cli/v3"
)
-type (
- authService struct {
- initDB func(ctx context.Context) error
- createAuthSource func(context.Context, *auth.Source) error
- updateAuthSource func(context.Context, *auth.Source) error
- getAuthSourceByID func(ctx context.Context, id int64) (*auth.Source, error)
- }
-)
-
func commonLdapCLIFlags() []cli.Flag {
return []cli.Flag{
&cli.StringFlag{
@@ -184,16 +175,6 @@ func microcmdAuthUpdateLdapSimpleAuth() *cli.Command {
}
}
-// newAuthService creates a service with default functions.
-func newAuthService() *authService {
- return &authService{
- initDB: initDB,
- createAuthSource: auth.CreateSource,
- updateAuthSource: auth.UpdateSource,
- getAuthSourceByID: auth.GetSourceByID,
- }
-}
-
// parseAuthSource assigns values on authSource according to command line flags.
func parseAuthSource(c *cli.Command, authSource *auth.Source) {
if c.IsSet("name") {
diff --git a/cmd/admin_auth_oauth.go b/cmd/admin_auth_oauth.go
index abdcd5d48a..8a756480cd 100644
--- a/cmd/admin_auth_oauth.go
+++ b/cmd/admin_auth_oauth.go
@@ -86,6 +86,11 @@ func oauthCLIFlags() []cli.Flag {
Value: nil,
Usage: "Scopes to request when to authenticate against this OAuth2 source",
},
+ &cli.StringFlag{
+ Name: "attribute-ssh-public-key",
+ Value: "",
+ Usage: "Claim name providing SSH public keys for this source",
+ },
&cli.StringFlag{
Name: "required-claim-name",
Value: "",
@@ -127,7 +132,7 @@ func microcmdAuthAddOauth() *cli.Command {
return &cli.Command{
Name: "add-oauth",
Usage: "Add new Oauth authentication source",
- Action: runAddOauth,
+ Action: newAuthService().addOauth,
Flags: oauthCLIFlags(),
}
}
@@ -136,7 +141,7 @@ func microcmdAuthUpdateOauth() *cli.Command {
return &cli.Command{
Name: "update-oauth",
Usage: "Update existing Oauth authentication source",
- Action: runUpdateOauth,
+ Action: newAuthService().updateOauth,
Flags: append(oauthCLIFlags()[:1], append([]cli.Flag{idFlag()}, oauthCLIFlags()[1:]...)...),
}
}
@@ -163,6 +168,7 @@ func parseOAuth2Config(_ context.Context, c *cli.Command) *oauth2.Source {
IconURL: c.String("icon-url"),
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
Scopes: c.StringSlice("scopes"),
+ AttributeSSHPublicKey: c.String("attribute-ssh-public-key"),
RequiredClaimName: c.String("required-claim-name"),
RequiredClaimValue: c.String("required-claim-value"),
GroupClaimName: c.String("group-claim-name"),
@@ -173,11 +179,11 @@ func parseOAuth2Config(_ context.Context, c *cli.Command) *oauth2.Source {
}
}
-func runAddOauth(ctx context.Context, c *cli.Command) error {
+func (a *authService) addOauth(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
defer cancel()
- if err := initDB(ctx); err != nil {
+ if err := a.initDB(ctx); err != nil {
return err
}
@@ -189,7 +195,7 @@ func runAddOauth(ctx context.Context, c *cli.Command) error {
}
}
- return auth_model.CreateSource(ctx, &auth_model.Source{
+ return a.createAuthSource(ctx, &auth_model.Source{
Type: auth_model.OAuth2,
Name: c.String("name"),
IsActive: true,
@@ -197,7 +203,7 @@ func runAddOauth(ctx context.Context, c *cli.Command) error {
})
}
-func runUpdateOauth(ctx context.Context, c *cli.Command) error {
+func (a *authService) updateOauth(ctx context.Context, c *cli.Command) error {
if !c.IsSet("id") {
return errors.New("--id flag is missing")
}
@@ -205,11 +211,11 @@ func runUpdateOauth(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
defer cancel()
- if err := initDB(ctx); err != nil {
+ if err := a.initDB(ctx); err != nil {
return err
}
- source, err := auth_model.GetSourceByID(ctx, c.Int64("id"))
+ source, err := a.getAuthSourceByID(ctx, c.Int64("id"))
if err != nil {
return err
}
@@ -244,6 +250,10 @@ func runUpdateOauth(ctx context.Context, c *cli.Command) error {
oAuth2Config.Scopes = c.StringSlice("scopes")
}
+ if c.IsSet("attribute-ssh-public-key") {
+ oAuth2Config.AttributeSSHPublicKey = c.String("attribute-ssh-public-key")
+ }
+
if c.IsSet("required-claim-name") {
oAuth2Config.RequiredClaimName = c.String("required-claim-name")
}
@@ -300,5 +310,5 @@ func runUpdateOauth(ctx context.Context, c *cli.Command) error {
oAuth2Config.CustomURLMapping = customURLMapping
source.Cfg = oAuth2Config
- return auth_model.UpdateSource(ctx, source)
+ return a.updateAuthSource(ctx, source)
}
diff --git a/cmd/admin_auth_oauth_test.go b/cmd/admin_auth_oauth_test.go
new file mode 100644
index 0000000000..ea5442e62d
--- /dev/null
+++ b/cmd/admin_auth_oauth_test.go
@@ -0,0 +1,704 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package cmd
+
+import (
+ "context"
+ "testing"
+
+ "forgejo.org/models/auth"
+ "forgejo.org/modules/test"
+ "forgejo.org/services/auth/source/oauth2"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "github.com/urfave/cli/v3"
+)
+
+func TestAddOauth(t *testing.T) {
+ // Mock cli functions to do not exit on error
+ defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
+
+ // Test cases
+ cases := []struct {
+ args []string
+ source *auth.Source
+ errMsg string
+ }{
+ // case 0
+ {
+ args: []string{
+ "oauth-test",
+ "--name", "oauth2 (via openidConnect) source full",
+ "--provider", "openidConnect",
+ "--key", "client id",
+ "--secret", "client secret",
+ "--auto-discover-url", "https://example.com/.well-known/openid-configuration",
+ "--use-custom-urls", "",
+ "--custom-tenant-id", "tenant id",
+ "--custom-auth-url", "https://example.com/auth",
+ "--custom-token-url", "https://example.com/token",
+ "--custom-profile-url", "https://example.com/profile",
+ "--custom-email-url", "https://example.com/email",
+ "--icon-url", "https://example.com/icon.svg",
+ "--skip-local-2fa",
+ "--scopes", "address",
+ "--scopes", "email",
+ "--scopes", "phone",
+ "--scopes", "profile",
+ "--attribute-ssh-public-key", "ssh_public_key",
+ "--required-claim-name", "can_access",
+ "--required-claim-value", "yes",
+ "--group-claim-name", "groups",
+ "--admin-group", "admin",
+ "--restricted-group", "restricted",
+ "--group-team-map", `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`,
+ "--group-team-map-removal",
+ },
+ source: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source full",
+ IsActive: true,
+ Cfg: &oauth2.Source{
+ Provider: "openidConnect",
+ ClientID: "client id",
+ ClientSecret: "client secret",
+ OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration",
+ CustomURLMapping: &oauth2.CustomURLMapping{
+ AuthURL: "https://example.com/auth",
+ TokenURL: "https://example.com/token",
+ ProfileURL: "https://example.com/profile",
+ EmailURL: "https://example.com/email",
+ Tenant: "tenant id",
+ },
+ IconURL: "https://example.com/icon.svg",
+ Scopes: []string{"address", "email", "phone", "profile"},
+ AttributeSSHPublicKey: "ssh_public_key",
+ RequiredClaimName: "can_access",
+ RequiredClaimValue: "yes",
+ GroupClaimName: "groups",
+ AdminGroup: "admin",
+ GroupTeamMap: `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`,
+ GroupTeamMapRemoval: true,
+ RestrictedGroup: "restricted",
+ SkipLocalTwoFA: true,
+ },
+ },
+ },
+ // case 1
+ {
+ args: []string{
+ "oauth-test",
+ "--name", "oauth2 (via openidConnect) source min",
+ "--provider", "openidConnect",
+ "--auto-discover-url", "https://example.com/.well-known/openid-configuration",
+ },
+ source: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source min",
+ IsActive: true,
+ Cfg: &oauth2.Source{
+ Provider: "openidConnect",
+ OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration",
+ Scopes: []string{},
+ },
+ },
+ },
+ // case 2
+ {
+ args: []string{
+ "oauth-test",
+ "--name", "oauth2 (via openidConnect) source `--use-custom-urls` required for `--custom-*` flags",
+ "--custom-tenant-id", "tenant id",
+ "--custom-auth-url", "https://example.com/auth",
+ "--custom-token-url", "https://example.com/token",
+ "--custom-profile-url", "https://example.com/profile",
+ "--custom-email-url", "https://example.com/email",
+ },
+ source: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source `--use-custom-urls` required for `--custom-*` flags",
+ IsActive: true,
+ Cfg: &oauth2.Source{
+ Scopes: []string{},
+ },
+ },
+ },
+ // case 3
+ {
+ args: []string{
+ "oauth-test",
+ "--name", "oauth2 (via openidConnect) source `--scopes` aggregates multiple uses",
+ "--provider", "openidConnect",
+ "--auto-discover-url", "https://example.com/.well-known/openid-configuration",
+ "--scopes", "address",
+ "--scopes", "email",
+ "--scopes", "phone",
+ "--scopes", "profile",
+ },
+ source: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source `--scopes` aggregates multiple uses",
+ IsActive: true,
+ Cfg: &oauth2.Source{
+ Provider: "openidConnect",
+ OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration",
+ Scopes: []string{"address", "email", "phone", "profile"},
+ },
+ },
+ },
+ // case 4
+ {
+ args: []string{
+ "oauth-test",
+ "--name", "oauth2 (via openidConnect) source `--scopes` supports commas as separators",
+ "--provider", "openidConnect",
+ "--auto-discover-url", "https://example.com/.well-known/openid-configuration",
+ "--scopes", "address,email,phone,profile",
+ },
+ source: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source `--scopes` supports commas as separators",
+ IsActive: true,
+ Cfg: &oauth2.Source{
+ Provider: "openidConnect",
+ OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration",
+ Scopes: []string{"address", "email", "phone", "profile"},
+ },
+ },
+ },
+ // case 5
+ {
+ args: []string{
+ "oauth-test",
+ "--name", "oauth2 (via openidConnect) source",
+ "--provider", "openidConnect",
+ },
+ errMsg: "invalid Auto Discovery URL: (this must be a valid URL starting with http:// or https://)",
+ },
+ // case 6
+ {
+ args: []string{
+ "oauth-test",
+ "--name", "oauth2 (via openidConnect) source",
+ "--provider", "openidConnect",
+ "--auto-discover-url", "example.com",
+ },
+ errMsg: "invalid Auto Discovery URL: example.com (this must be a valid URL starting with http:// or https://)",
+ },
+ }
+
+ for n, c := range cases {
+ // Mock functions.
+ var createdAuthSource *auth.Source
+ service := &authService{
+ initDB: func(context.Context) error {
+ return nil
+ },
+ createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
+ createdAuthSource = authSource
+ return nil
+ },
+ updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
+ assert.FailNow(t, "should not call updateAuthSource", "case: %d", n)
+ return nil
+ },
+ getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
+ assert.FailNow(t, "should not call getAuthSourceByID", "case: %d", n)
+ return nil, nil
+ },
+ }
+
+ // Create a copy of command to test
+ app := cli.Command{}
+ app.Flags = microcmdAuthAddOauth().Flags
+ app.Action = service.addOauth
+
+ // Run it
+ err := app.Run(t.Context(), c.args)
+ if c.errMsg != "" {
+ assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
+ } else {
+ require.NoError(t, err, "case %d: should have no errors", n)
+ assert.Equal(t, c.source, createdAuthSource, "case %d: wrong authSource", n)
+ }
+ }
+}
+
+func TestUpdateOauth(t *testing.T) {
+ // Mock cli functions to do not exit on error
+ defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
+
+ // Test cases
+ cases := []struct {
+ args []string
+ id int64
+ existingAuthSource *auth.Source
+ authSource *auth.Source
+ errMsg string
+ }{
+ // case 0
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "23",
+ "--name", "oauth2 (via openidConnect) source full",
+ "--provider", "openidConnect",
+ "--key", "client id",
+ "--secret", "client secret",
+ "--auto-discover-url", "https://example.com/.well-known/openid-configuration",
+ "--use-custom-urls", "",
+ "--custom-tenant-id", "tenant id",
+ "--custom-auth-url", "https://example.com/auth",
+ "--custom-token-url", "https://example.com/token",
+ "--custom-profile-url", "https://example.com/profile",
+ "--custom-email-url", "https://example.com/email",
+ "--icon-url", "https://example.com/icon.svg",
+ "--skip-local-2fa",
+ "--scopes", "address",
+ "--scopes", "email",
+ "--scopes", "phone",
+ "--scopes", "profile",
+ "--attribute-ssh-public-key", "ssh_public_key",
+ "--required-claim-name", "can_access",
+ "--required-claim-value", "yes",
+ "--group-claim-name", "groups",
+ "--admin-group", "admin",
+ "--restricted-group", "restricted",
+ "--group-team-map", `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`,
+ "--group-team-map-removal",
+ },
+ id: 23,
+ existingAuthSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{},
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source full",
+ Cfg: &oauth2.Source{
+ Provider: "openidConnect",
+ ClientID: "client id",
+ ClientSecret: "client secret",
+ OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration",
+ CustomURLMapping: &oauth2.CustomURLMapping{
+ AuthURL: "https://example.com/auth",
+ TokenURL: "https://example.com/token",
+ ProfileURL: "https://example.com/profile",
+ EmailURL: "https://example.com/email",
+ Tenant: "tenant id",
+ },
+ IconURL: "https://example.com/icon.svg",
+ Scopes: []string{"address", "email", "phone", "profile"},
+ AttributeSSHPublicKey: "ssh_public_key",
+ RequiredClaimName: "can_access",
+ RequiredClaimValue: "yes",
+ GroupClaimName: "groups",
+ AdminGroup: "admin",
+ GroupTeamMap: `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`,
+ GroupTeamMapRemoval: true,
+ RestrictedGroup: "restricted",
+ // `--skip-local-2fa` is currently ignored.
+ // SkipLocalTwoFA: true,
+ },
+ },
+ },
+ // case 1
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ },
+ },
+ },
+ // case 2
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--name", "oauth2 (via openidConnect) source full",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source full",
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ },
+ },
+ },
+ // case 3
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--provider", "openidConnect",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ Provider: "openidConnect",
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ },
+ },
+ },
+ // case 4
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--key", "client id",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ ClientID: "client id",
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ },
+ },
+ },
+ // case 5
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--secret", "client secret",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ ClientSecret: "client secret",
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ },
+ },
+ },
+ // case 6
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--auto-discover-url", "https://example.com/.well-known/openid-configuration",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ OpenIDConnectAutoDiscoveryURL: "https://example.com/.well-known/openid-configuration",
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ },
+ },
+ },
+ // case 7
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--use-custom-urls", "",
+ "--custom-tenant-id", "tenant id",
+ "--custom-auth-url", "https://example.com/auth",
+ "--custom-token-url", "https://example.com/token",
+ "--custom-profile-url", "https://example.com/profile",
+ "--custom-email-url", "https://example.com/email",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{
+ AuthURL: "https://example.com/auth",
+ TokenURL: "https://example.com/token",
+ ProfileURL: "https://example.com/profile",
+ EmailURL: "https://example.com/email",
+ Tenant: "tenant id",
+ },
+ },
+ },
+ },
+ // case 8
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--name", "oauth2 (via openidConnect) source `--use-custom-urls` required for `--custom-*` flags",
+ "--custom-tenant-id", "tenant id",
+ "--custom-auth-url", "https://example.com/auth",
+ "--custom-token-url", "https://example.com/token",
+ "--custom-profile-url", "https://example.com/profile",
+ "--custom-email-url", "https://example.com/email",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source `--use-custom-urls` required for `--custom-*` flags",
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ },
+ },
+ },
+ // case 9
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--icon-url", "https://example.com/icon.svg",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ IconURL: "https://example.com/icon.svg",
+ },
+ },
+ },
+ // case 10
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--name", "oauth2 (via openidConnect) source `--skip-local-2fa` is currently ignored",
+ "--skip-local-2fa",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source `--skip-local-2fa` is currently ignored",
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ // `--skip-local-2fa` is currently ignored.
+ // SkipLocalTwoFA: true,
+ },
+ },
+ },
+ // case 11
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--name", "oauth2 (via openidConnect) source `--scopes` aggregates multiple uses",
+ "--scopes", "address",
+ "--scopes", "email",
+ "--scopes", "phone",
+ "--scopes", "profile",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source `--scopes` aggregates multiple uses",
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ Scopes: []string{"address", "email", "phone", "profile"},
+ },
+ },
+ },
+ // case 12
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--name", "oauth2 (via openidConnect) source `--scopes` supports commas as separators",
+ "--scopes", "address,email,phone,profile",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Name: "oauth2 (via openidConnect) source `--scopes` supports commas as separators",
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ Scopes: []string{"address", "email", "phone", "profile"},
+ },
+ },
+ },
+ // case 13
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--attribute-ssh-public-key", "ssh_public_key",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ AttributeSSHPublicKey: "ssh_public_key",
+ },
+ },
+ },
+ // case 14
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--required-claim-name", "can_access",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ RequiredClaimName: "can_access",
+ },
+ },
+ },
+ // case 15
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--required-claim-value", "yes",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ RequiredClaimValue: "yes",
+ },
+ },
+ },
+ // case 16
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--group-claim-name", "groups",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ GroupClaimName: "groups",
+ },
+ },
+ },
+ // case 17
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--admin-group", "admin",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ AdminGroup: "admin",
+ },
+ },
+ },
+ // case 18
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--restricted-group", "restricted",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ RestrictedGroup: "restricted",
+ },
+ },
+ },
+ // case 19
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--group-team-map", `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`,
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ GroupTeamMap: `{"org_a_team_1": {"organization-a": ["Team 1"]}, "org_a_all_teams": {"organization-a": ["Team 1", "Team 2", "Team 3"]}}`,
+ },
+ },
+ },
+ // case 20
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "1",
+ "--group-team-map-removal",
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ GroupTeamMapRemoval: true,
+ },
+ },
+ },
+ // case 21
+ {
+ args: []string{
+ "oauth-test",
+ "--id", "23",
+ "--group-team-map-removal=false",
+ },
+ id: 23,
+ existingAuthSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ GroupTeamMapRemoval: true,
+ },
+ },
+ authSource: &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{
+ CustomURLMapping: &oauth2.CustomURLMapping{},
+ GroupTeamMapRemoval: false,
+ },
+ },
+ },
+ // case 22
+ {
+ args: []string{
+ "oauth-test",
+ },
+ errMsg: "--id flag is missing",
+ },
+ }
+
+ for n, c := range cases {
+ // Mock functions.
+ var updatedAuthSource *auth.Source
+ service := &authService{
+ initDB: func(context.Context) error {
+ return nil
+ },
+ createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
+ assert.FailNow(t, "should not call createAuthSource", "case: %d", n)
+ return nil
+ },
+ updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
+ updatedAuthSource = authSource
+ return nil
+ },
+ getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
+ if c.id != 0 {
+ assert.Equal(t, c.id, id, "case %d: wrong id", n)
+ }
+ if c.existingAuthSource != nil {
+ return c.existingAuthSource, nil
+ }
+ return &auth.Source{
+ Type: auth.OAuth2,
+ Cfg: &oauth2.Source{},
+ }, nil
+ },
+ }
+
+ // Create a copy of command to test
+ app := cli.Command{}
+ app.Flags = microcmdAuthUpdateOauth().Flags
+ app.Action = service.updateOauth
+
+ // Run it
+ err := app.Run(t.Context(), c.args)
+ if c.errMsg != "" {
+ assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
+ } else {
+ require.NoError(t, err, "case %d: should have no errors", n)
+ assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n)
+ }
+ }
+}
diff --git a/cmd/manager_logging.go b/cmd/manager_logging.go
index c543afe872..c18bfa919b 100644
--- a/cmd/manager_logging.go
+++ b/cmd/manager_logging.go
@@ -44,6 +44,11 @@ func defaultLoggingFlags() []cli.Flag {
Aliases: []string{"e"},
Usage: "Matching expression for the logger",
},
+ &cli.StringFlag{
+ Name: "exclusion",
+ Aliases: []string{"x"},
+ Usage: "Exclusion for the logger",
+ },
&cli.StringFlag{
Name: "prefix",
Aliases: []string{"p"},
@@ -286,6 +291,9 @@ func commonAddLogger(ctx context.Context, c *cli.Command, mode string, vals map[
if len(c.String("expression")) > 0 {
vals["expression"] = c.String("expression")
}
+ if len(c.String("exclusion")) > 0 {
+ vals["exclusion"] = c.String("exclusion")
+ }
if len(c.String("prefix")) > 0 {
vals["prefix"] = c.String("prefix")
}
diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index 1b8d4c6697..71598663b2 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -631,6 +631,7 @@ LEVEL = Info
;LEVEL=
;FLAGS = stdflags or journald
;EXPRESSION =
+;EXCLUSION =
;PREFIX =
;COLORIZE = false
;;
@@ -1767,6 +1768,9 @@ LEVEL = Info
;; Use PASSWD = `your password` for quoting if you use special characters in the password.
;PASSWD =
;;
+;; Alternative location to specify mailer password. You cannot specify both this and PASSWD, and must pick one
+;PASSWD_URI = file:/etc/forgejo/mailer_passwd
+;;
;; Send mails only in plain text, without HTML alternative
;SEND_AS_PLAIN_TEXT = false
;;
@@ -1819,6 +1823,9 @@ LEVEL = Info
;; Password of the receiving account
;PASSWORD =
;;
+;; Alternative location to specify password of the receiving account. You cannot specify both this and PASSWORD, and must pick one
+;PASSWORD_URI = file:/etc/forgejo/email_incoming_password
+;;
;; Whether the IMAP server uses TLS.
;USE_TLS = false
;;
diff --git a/go.mod b/go.mod
index 33ad5dbc67..139095099b 100644
--- a/go.mod
+++ b/go.mod
@@ -2,7 +2,7 @@ module forgejo.org
go 1.24
-toolchain go1.24.4
+toolchain go1.24.5
require (
code.forgejo.org/f3/gof3/v3 v3.11.0
@@ -24,7 +24,7 @@ require (
github.com/ProtonMail/go-crypto v1.3.0
github.com/PuerkitoBio/goquery v1.10.3
github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2
- github.com/alecthomas/chroma/v2 v2.18.0
+ github.com/alecthomas/chroma/v2 v2.19.0
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
github.com/blevesearch/bleve/v2 v2.5.2
github.com/buildkite/terminal-to-html/v3 v3.16.8
@@ -42,21 +42,21 @@ require (
github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73
github.com/go-chi/chi/v5 v5.2.2
- github.com/go-chi/cors v1.2.1
+ github.com/go-chi/cors v1.2.2
github.com/go-co-op/gocron v1.37.0
github.com/go-enry/go-enry/v2 v2.9.2
github.com/go-git/go-git/v5 v5.13.2
github.com/go-ldap/ldap/v3 v3.4.6
github.com/go-openapi/spec v0.21.0
github.com/go-sql-driver/mysql v1.9.3
- github.com/go-webauthn/webauthn v0.13.0
+ github.com/go-webauthn/webauthn v0.13.1
github.com/gobwas/glob v0.2.3
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
github.com/golang-jwt/jwt/v5 v5.2.2
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/google/go-github/v64 v64.0.0
- github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e
+ github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5
github.com/google/uuid v1.6.0
github.com/gorilla/feeds v1.2.0
github.com/gorilla/sessions v1.4.0
@@ -99,13 +99,13 @@ require (
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
gitlab.com/gitlab-org/api/client-go v0.130.1
go.uber.org/mock v0.5.2
- golang.org/x/crypto v0.39.0
+ golang.org/x/crypto v0.40.0
golang.org/x/image v0.27.0
- golang.org/x/net v0.41.0
+ golang.org/x/net v0.42.0
golang.org/x/oauth2 v0.30.0
- golang.org/x/sync v0.15.0
- golang.org/x/sys v0.33.0
- golang.org/x/text v0.26.0
+ golang.org/x/sync v0.16.0
+ golang.org/x/sys v0.34.0
+ golang.org/x/text v0.27.0
google.golang.org/protobuf v1.36.4
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ini.v1 v1.67.0
@@ -170,7 +170,7 @@ require (
github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
- github.com/go-webauthn/x v0.1.21 // indirect
+ github.com/go-webauthn/x v0.1.22 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
@@ -244,7 +244,7 @@ require (
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
-replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.28.0
+replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.29.0
replace github.com/mholt/archiver/v3 => code.forgejo.org/forgejo/archiver/v3 v3.5.1
diff --git a/go.sum b/go.sum
index 45497a1b49..3c906b45c6 100644
--- a/go.sum
+++ b/go.sum
@@ -4,8 +4,8 @@ code.forgejo.org/f3/gof3/v3 v3.11.0 h1:f/xToKwqTgxG6PYxvewywjDQyCcyHEEJ6sZqUitFs
code.forgejo.org/f3/gof3/v3 v3.11.0/go.mod h1:4FaRUNSQGBiD1M0DuB0yNv+Z2wMtlOeckgygHSSq4KQ=
code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251 h1:HTZl3CBk3ABNYtFI6TPLvJgGKFIhKT5CBk0sbOtkDKU=
code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:PphB88CPbx601QrWPMZATeorACeVmQlyv3u+uUMbSaM=
-code.forgejo.org/forgejo/act v1.28.0 h1:96njNC7C1YNyjWq5OWvLZMF/nw0PMthzIA8Nwbnn7jo=
-code.forgejo.org/forgejo/act v1.28.0/go.mod h1:dFuiwAmD5vyrzecysHB2kL/GM3wRpoVPl+WdbCTC8Bs=
+code.forgejo.org/forgejo/act v1.29.0 h1:CPiI0LRPU0f6gUdQj1ZVax0ySc8CfegY4hiRsymdZU0=
+code.forgejo.org/forgejo/act v1.29.0/go.mod h1:RPqtuaI2FkC1SVOaYCRODo5jIfoMTBVgEOOP3Sdiuh4=
code.forgejo.org/forgejo/archiver/v3 v3.5.1 h1:UmmbA7D5550uf71SQjarmrn6yKwOGxtEjb3jaYYtmSE=
code.forgejo.org/forgejo/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
code.forgejo.org/forgejo/go-rpmutils v1.0.0 h1:RZGGeKt70p/WaIEL97pyT6uiiEIoN8/aLmS5Z6WmX0M=
@@ -62,8 +62,8 @@ github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2/go.mod h1:JitQWJ8JuV4Y
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
-github.com/alecthomas/chroma/v2 v2.18.0 h1:6h53Q4hW83SuF+jcsp7CVhLsMozzvQvO8HBbKQW+gn4=
-github.com/alecthomas/chroma/v2 v2.18.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
+github.com/alecthomas/chroma/v2 v2.19.0 h1:Im+SLRgT8maArxv81mULDWN8oKxkzboH07CHesxElq4=
+github.com/alecthomas/chroma/v2 v2.19.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
@@ -215,8 +215,8 @@ github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkPro
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
-github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
-github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
+github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE=
+github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
github.com/go-enry/go-enry/v2 v2.9.2 h1:giOQAtCgBX08kosrX818DCQJTCNtKwoPBGu0qb6nKTY=
@@ -250,10 +250,10 @@ github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI6
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
-github.com/go-webauthn/webauthn v0.13.0 h1:cJIL1/1l+22UekVhipziAaSgESJxokYkowUqAIsWs0Y=
-github.com/go-webauthn/webauthn v0.13.0/go.mod h1:Oy9o2o79dbLKRPZWWgRIOdtBGAhKnDIaBp2PFkICRHs=
-github.com/go-webauthn/x v0.1.21 h1:nFbckQxudvHEJn2uy1VEi713MeSpApoAv9eRqsb9AdQ=
-github.com/go-webauthn/x v0.1.21/go.mod h1:sEYohtg1zL4An1TXIUIQ5csdmoO+WO0R4R2pGKaHYKA=
+github.com/go-webauthn/webauthn v0.13.1 h1:Q3/GLXsckVJUPE+BGR6ex26yRIiZ/X2ITaMeSkOftuc=
+github.com/go-webauthn/webauthn v0.13.1/go.mod h1:HeaBromTjgMg1sHZOzyjEiqcrk4Og7mxafDTWDepaXI=
+github.com/go-webauthn/x v0.1.22 h1:rHilV/rYXawarI0uA3uZ5nhLb30Ex8RgbVAsOSt/57o=
+github.com/go-webauthn/x v0.1.22/go.mod h1:+iV9BF4OsvLYzETdc0lmQO2webTos10oH6QydSoWxDM=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
@@ -307,8 +307,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
-github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
-github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
+github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 h1:xhMrHhTJ6zxu3gA4enFM9MLn9AY7613teCdFnlUVbSQ=
+github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -585,8 +585,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
-golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
-golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
+golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
+golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w=
@@ -614,8 +614,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
-golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
-golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
+golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
+golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -627,8 +627,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
-golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
+golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -654,8 +654,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
-golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
+golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -665,8 +665,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
-golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
-golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
+golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
+golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -677,8 +677,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
-golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
-golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
+golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
+golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/models/actions/run.go b/models/actions/run.go
index 55def805ed..69592120e9 100644
--- a/models/actions/run.go
+++ b/models/actions/run.go
@@ -284,16 +284,10 @@ func GetLatestRun(ctx context.Context, repoID int64) (*ActionRun, error) {
return &run, nil
}
-// GetRunBefore returns the last run that completed a given timestamp (not inclusive).
-func GetRunBefore(ctx context.Context, repoID int64, timestamp timeutil.TimeStamp) (*ActionRun, error) {
- var run ActionRun
- has, err := db.GetEngine(ctx).Where("repo_id=? AND stopped IS NOT NULL AND stopped", repoID, timestamp).OrderBy("stopped DESC").Limit(1).Get(&run)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, fmt.Errorf("run before: %w", util.ErrNotExist)
- }
- return &run, nil
+func GetRunBefore(ctx context.Context, _ *ActionRun) (*ActionRun, error) {
+ // TODO return the most recent run related to the run given in argument
+ // see https://codeberg.org/forgejo/user-research/issues/63 for context
+ return nil, nil
}
func GetLatestRunForBranchAndWorkflow(ctx context.Context, repoID int64, branch, workflowFile, event string) (*ActionRun, error) {
diff --git a/models/actions/run_test.go b/models/actions/run_test.go
index 11b03022ff..c9a552a2b2 100644
--- a/models/actions/run_test.go
+++ b/models/actions/run_test.go
@@ -5,92 +5,7 @@ package actions
import (
"testing"
- "time"
-
- "forgejo.org/models/db"
- "forgejo.org/models/unittest"
- "forgejo.org/modules/timeutil"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
)
func TestGetRunBefore(t *testing.T) {
- require.NoError(t, unittest.PrepareTestDatabase())
-
- // this repo is part of the test database requiring loading "repository.yml" in main_test.go
- var repoID int64 = 1
-
- workflowID := "test_workflow"
-
- // third completed run
- time1, err := time.Parse(time.RFC3339, "2024-07-31T15:47:55+08:00")
- require.NoError(t, err)
- timeutil.MockSet(time1)
- run1 := ActionRun{
- ID: 1,
- Index: 1,
- RepoID: repoID,
- Stopped: timeutil.TimeStampNow(),
- WorkflowID: workflowID,
- }
-
- // fourth completed run
- time2, err := time.Parse(time.RFC3339, "2024-08-31T15:47:55+08:00")
- require.NoError(t, err)
- timeutil.MockSet(time2)
- run2 := ActionRun{
- ID: 2,
- Index: 2,
- RepoID: repoID,
- Stopped: timeutil.TimeStampNow(),
- WorkflowID: workflowID,
- }
-
- // second completed run
- time3, err := time.Parse(time.RFC3339, "2024-07-31T15:47:54+08:00")
- require.NoError(t, err)
- timeutil.MockSet(time3)
- run3 := ActionRun{
- ID: 3,
- Index: 3,
- RepoID: repoID,
- Stopped: timeutil.TimeStampNow(),
- WorkflowID: workflowID,
- }
-
- // first completed run
- time4, err := time.Parse(time.RFC3339, "2024-06-30T15:47:54+08:00")
- require.NoError(t, err)
- timeutil.MockSet(time4)
- run4 := ActionRun{
- ID: 4,
- Index: 4,
- RepoID: repoID,
- Stopped: timeutil.TimeStampNow(),
- WorkflowID: workflowID,
- }
- require.NoError(t, db.Insert(db.DefaultContext, &run1))
- runBefore, err := GetRunBefore(db.DefaultContext, repoID, run1.Stopped)
- // there is no run before run1
- require.Error(t, err)
- require.Nil(t, runBefore)
-
- // now there is only run3 before run1
- require.NoError(t, db.Insert(db.DefaultContext, &run3))
- runBefore, err = GetRunBefore(db.DefaultContext, repoID, run1.Stopped)
- require.NoError(t, err)
- assert.Equal(t, run3.ID, runBefore.ID)
-
- // there still is only run3 before run1
- require.NoError(t, db.Insert(db.DefaultContext, &run2))
- runBefore, err = GetRunBefore(db.DefaultContext, repoID, run1.Stopped)
- require.NoError(t, err)
- assert.Equal(t, run3.ID, runBefore.ID)
-
- // run4 is further away from run1
- require.NoError(t, db.Insert(db.DefaultContext, &run4))
- runBefore, err = GetRunBefore(db.DefaultContext, repoID, run1.Stopped)
- require.NoError(t, err)
- assert.Equal(t, run3.ID, runBefore.ID)
}
diff --git a/models/asymkey/main_test.go b/models/asymkey/main_test.go
index 316e8f1d54..aa13a93f0a 100644
--- a/models/asymkey/main_test.go
+++ b/models/asymkey/main_test.go
@@ -15,8 +15,6 @@ func TestMain(m *testing.M) {
"gpg_key.yml",
"public_key.yml",
"TestParseCommitWithSSHSignature/public_key.yml",
- "deploy_key.yml",
- "gpg_key_import.yml",
"user.yml",
"email_address.yml",
},
diff --git a/models/db/context.go b/models/db/context.go
index 35526936af..3e035cd733 100644
--- a/models/db/context.go
+++ b/models/db/context.go
@@ -141,7 +141,7 @@ func TxContext(parentCtx context.Context) (*Context, Committer, error) {
return nil, nil, err
}
- return newContext(DefaultContext, sess, true), sess, nil
+ return newContext(parentCtx, sess, true), sess, nil
}
// WithTx represents executing database operations on a transaction, if the transaction exist,
diff --git a/models/db/context_test.go b/models/db/context_test.go
index 7ab327b7e9..d12d79ebe1 100644
--- a/models/db/context_test.go
+++ b/models/db/context_test.go
@@ -84,4 +84,16 @@ func TestTxContext(t *testing.T) {
return nil
}))
}
+
+ t.Run("Reuses parent context", func(t *testing.T) {
+ type unique struct{}
+
+ ctx := context.WithValue(db.DefaultContext, unique{}, "yes!")
+ assert.False(t, db.InTransaction(ctx))
+
+ require.NoError(t, db.WithTx(ctx, func(ctx context.Context) error {
+ assert.Equal(t, "yes!", ctx.Value(unique{}))
+ return nil
+ }))
+ })
}
diff --git a/models/db/engine.go b/models/db/engine.go
index 05a119b08d..76025f7d67 100755
--- a/models/db/engine.go
+++ b/models/db/engine.go
@@ -15,6 +15,7 @@ import (
"strings"
"time"
+ "forgejo.org/modules/container"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
@@ -438,3 +439,12 @@ func GetMasterEngine(x Engine) (*xorm.Engine, error) {
return engine, nil
}
+
+// GetTableNames returns the table name of all registered models.
+func GetTableNames() container.Set[string] {
+ names := make(container.Set[string])
+ for _, table := range tables {
+ names.Add(x.TableName(table))
+ }
+ return names
+}
diff --git a/models/db/table_names_test.go b/models/db/table_names_test.go
new file mode 100644
index 0000000000..176ce9905d
--- /dev/null
+++ b/models/db/table_names_test.go
@@ -0,0 +1,40 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package db
+
+import (
+ "slices"
+ "testing"
+
+ "forgejo.org/modules/test"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestGetTableNames(t *testing.T) {
+ t.Run("Simple", func(t *testing.T) {
+ defer test.MockVariableValue(&tables, []any{new(GPGKey)})()
+
+ assert.Equal(t, []string{"gpg_key"}, GetTableNames().Values())
+ })
+
+ t.Run("Multiple tables", func(t *testing.T) {
+ defer test.MockVariableValue(&tables, []any{new(GPGKey), new(User), new(BlockedUser)})()
+
+ tableNames := GetTableNames().Values()
+ slices.Sort(tableNames)
+
+ assert.Equal(t, []string{"forgejo_blocked_user", "gpg_key", "user"}, tableNames)
+ })
+}
+
+type GPGKey struct{}
+
+type User struct{}
+
+type BlockedUser struct{}
+
+func (*BlockedUser) TableName() string {
+ return "forgejo_blocked_user"
+}
diff --git a/models/fixtures/TestActivateUserEmail/email_address.yml b/models/fixtures/TestActivateUserEmail/email_address.yml
new file mode 100644
index 0000000000..cf41ff8241
--- /dev/null
+++ b/models/fixtures/TestActivateUserEmail/email_address.yml
@@ -0,0 +1,7 @@
+-
+ id: 1001
+ uid: 1001
+ email: AnotherTestUserWithUpperCaseEmail@otto.splvs.net
+ lower_email: anothertestuserwithuppercaseemail@otto.splvs.net
+ is_activated: false
+ is_primary: true
diff --git a/models/fixtures/TestActivateUserEmail/user.yml b/models/fixtures/TestActivateUserEmail/user.yml
new file mode 100644
index 0000000000..0a68e70a4a
--- /dev/null
+++ b/models/fixtures/TestActivateUserEmail/user.yml
@@ -0,0 +1,12 @@
+-
+ id: 1001
+ lower_name: user1001
+ name: user1001
+ full_name: User That loves Upper Cases
+ email: AnotherTestUserWithUpperCaseEmail@otto.splvs.net
+ passwd: ZogKvWdyEx:password
+ passwd_hash_algo: dummy
+ avatar: ''
+ avatar_email: anothertestuserwithuppercaseemail@otto.splvs.net
+ login_name: user1
+ created_unix: 1672578000
diff --git a/models/fixtures/action_variable.yml b/models/fixtures/action_variable.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/action_variable.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/deploy_key.yml b/models/fixtures/deploy_key.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/deploy_key.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/external_login_user.yml b/models/fixtures/external_login_user.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/external_login_user.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/federated_user.yml b/models/fixtures/federated_user.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/federated_user.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/federation_host.yml b/models/fixtures/federation_host.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/federation_host.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/gpg_key_import.yml b/models/fixtures/gpg_key_import.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/gpg_key_import.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/label.yml b/models/fixtures/label.yml
index acfac74968..84c2a7f418 100644
--- a/models/fixtures/label.yml
+++ b/models/fixtures/label.yml
@@ -3,6 +3,7 @@
repo_id: 1
org_id: 0
name: label1
+ description: 'First label'
color: '#abcdef'
exclusive: false
num_issues: 2
@@ -107,3 +108,26 @@
num_issues: 0
num_closed_issues: 0
archived_unix: 0
+
+-
+ id: 11
+ repo_id: 3
+ org_id: 0
+ name: " /'?&"
+ description: "Malicious label ' "
+ color: '#000000'
+ exclusive: true
+ num_issues: 0
+ num_closed_issues: 0
+ archived_unix: 0
+
+-
+ id: 12
+ repo_id: 3
+ org_id: 0
+ name: 'archived label<>'
+ color: '#000000'
+ exclusive: false
+ num_issues: 0
+ num_closed_issues: 0
+ archived_unix: 2991092130
diff --git a/models/fixtures/login_source.yml b/models/fixtures/login_source.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/login_source.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/protected_branch.yml b/models/fixtures/protected_branch.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/protected_branch.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/pull_auto_merge.yml b/models/fixtures/pull_auto_merge.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/pull_auto_merge.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/push_mirror.yml b/models/fixtures/push_mirror.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/push_mirror.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/repo_archiver.yml b/models/fixtures/repo_archiver.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/repo_archiver.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/repo_indexer_status.yml b/models/fixtures/repo_indexer_status.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/repo_indexer_status.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/fixtures/secret.yml b/models/fixtures/secret.yml
deleted file mode 100644
index ca780a73aa..0000000000
--- a/models/fixtures/secret.yml
+++ /dev/null
@@ -1 +0,0 @@
-[] # empty
diff --git a/models/forgejo_migrations/main_test.go b/models/forgejo_migrations/main_test.go
index 031fe8090d..2246e327f0 100644
--- a/models/forgejo_migrations/main_test.go
+++ b/models/forgejo_migrations/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"testing"
diff --git a/models/forgejo_migrations/migrate.go b/models/forgejo_migrations/migrate.go
index 737350b019..fcea69d23f 100644
--- a/models/forgejo_migrations/migrate.go
+++ b/models/forgejo_migrations/migrate.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"context"
@@ -108,7 +108,9 @@ var migrations = []*Migration{
// v33 -> v34
NewMigration("Add `notify-email` column to `action_run` table", AddNotifyEmailToActionRun),
// v34 -> v35
- NewMigration("Add index to `stopped` column in `action_run` table", AddIndexToActionRunStopped),
+ NewMigration("Noop because of https://codeberg.org/forgejo/forgejo/issues/8373", NoopAddIndexToActionRunStopped),
+ // v35 -> v36
+ NewMigration("Fix wiki unit default permission", FixWikiUnitDefaultPermission),
}
// GetCurrentDBVersion returns the current Forgejo database version.
diff --git a/models/forgejo_migrations/migrate_test.go b/models/forgejo_migrations/migrate_test.go
index 20653929a3..9d16c9fe1c 100644
--- a/models/forgejo_migrations/migrate_test.go
+++ b/models/forgejo_migrations/migrate_test.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"testing"
diff --git a/models/forgejo_migrations/v13.go b/models/forgejo_migrations/v13.go
index 614f68249d..ba4183885e 100644
--- a/models/forgejo_migrations/v13.go
+++ b/models/forgejo_migrations/v13.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v14.go b/models/forgejo_migrations/v14.go
index 53f1ef2223..65b857d343 100644
--- a/models/forgejo_migrations/v14.go
+++ b/models/forgejo_migrations/v14.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"forgejo.org/models/migrations/base"
diff --git a/models/forgejo_migrations/v15.go b/models/forgejo_migrations/v15.go
index 5e5588dd05..a63199ab19 100644
--- a/models/forgejo_migrations/v15.go
+++ b/models/forgejo_migrations/v15.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"time"
diff --git a/models/forgejo_migrations/v16.go b/models/forgejo_migrations/v16.go
index f80bfc5268..a7d4d5d590 100644
--- a/models/forgejo_migrations/v16.go
+++ b/models/forgejo_migrations/v16.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v17.go b/models/forgejo_migrations/v17.go
index d6e2983d00..8ef6f2c681 100644
--- a/models/forgejo_migrations/v17.go
+++ b/models/forgejo_migrations/v17.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v18.go b/models/forgejo_migrations/v18.go
index e6c1493f0e..e39b0cbf10 100644
--- a/models/forgejo_migrations/v18.go
+++ b/models/forgejo_migrations/v18.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v19.go b/models/forgejo_migrations/v19.go
index 69b7746eb1..43d279dcb0 100644
--- a/models/forgejo_migrations/v19.go
+++ b/models/forgejo_migrations/v19.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v1_20/v1.go b/models/forgejo_migrations/v1_20/v1.go
index 72beaf23de..f0cb125557 100644
--- a/models/forgejo_migrations/v1_20/v1.go
+++ b/models/forgejo_migrations/v1_20/v1.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_v1_20 //nolint:revive
+package forgejo_v1_20
import (
"forgejo.org/modules/timeutil"
diff --git a/models/forgejo_migrations/v1_20/v2.go b/models/forgejo_migrations/v1_20/v2.go
index 39f3b58924..3f79ac3801 100644
--- a/models/forgejo_migrations/v1_20/v2.go
+++ b/models/forgejo_migrations/v1_20/v2.go
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
-package forgejo_v1_20 //nolint:revive
+package forgejo_v1_20
import (
"xorm.io/xorm"
diff --git a/models/forgejo_migrations/v1_20/v3.go b/models/forgejo_migrations/v1_20/v3.go
index cce227e6eb..49530df556 100644
--- a/models/forgejo_migrations/v1_20/v3.go
+++ b/models/forgejo_migrations/v1_20/v3.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_v1_20 //nolint:revive
+package forgejo_v1_20
import (
"forgejo.org/modules/timeutil"
diff --git a/models/forgejo_migrations/v1_22/main_test.go b/models/forgejo_migrations/v1_22/main_test.go
index 03c4c5272c..d6a5bdacee 100644
--- a/models/forgejo_migrations/v1_22/main_test.go
+++ b/models/forgejo_migrations/v1_22/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"testing"
diff --git a/models/forgejo_migrations/v1_22/v10.go b/models/forgejo_migrations/v1_22/v10.go
index 819800ae71..cf45abdd24 100644
--- a/models/forgejo_migrations/v1_22/v10.go
+++ b/models/forgejo_migrations/v1_22/v10.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"xorm.io/xorm"
diff --git a/models/forgejo_migrations/v1_22/v11.go b/models/forgejo_migrations/v1_22/v11.go
index 17bb592379..f0f92bd04c 100644
--- a/models/forgejo_migrations/v1_22/v11.go
+++ b/models/forgejo_migrations/v1_22/v11.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"forgejo.org/modules/timeutil"
diff --git a/models/forgejo_migrations/v1_22/v12.go b/models/forgejo_migrations/v1_22/v12.go
index 6822524705..51354bd3c2 100644
--- a/models/forgejo_migrations/v1_22/v12.go
+++ b/models/forgejo_migrations/v1_22/v12.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v1_22/v4.go b/models/forgejo_migrations/v1_22/v4.go
index f1195f5f66..499d377bb4 100644
--- a/models/forgejo_migrations/v1_22/v4.go
+++ b/models/forgejo_migrations/v1_22/v4.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"xorm.io/xorm"
diff --git a/models/forgejo_migrations/v1_22/v5.go b/models/forgejo_migrations/v1_22/v5.go
index 55f9fe1338..1671d3eed2 100644
--- a/models/forgejo_migrations/v1_22/v5.go
+++ b/models/forgejo_migrations/v1_22/v5.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"xorm.io/xorm"
diff --git a/models/forgejo_migrations/v1_22/v6.go b/models/forgejo_migrations/v1_22/v6.go
index 1a4874872c..072f8e6a15 100644
--- a/models/forgejo_migrations/v1_22/v6.go
+++ b/models/forgejo_migrations/v1_22/v6.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"xorm.io/xorm"
diff --git a/models/forgejo_migrations/v1_22/v7.go b/models/forgejo_migrations/v1_22/v7.go
index b42dd1af67..e7f6eb412b 100644
--- a/models/forgejo_migrations/v1_22/v7.go
+++ b/models/forgejo_migrations/v1_22/v7.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"xorm.io/xorm"
diff --git a/models/forgejo_migrations/v1_22/v8.go b/models/forgejo_migrations/v1_22/v8.go
index 2d3c0c594b..f23b00d2ad 100644
--- a/models/forgejo_migrations/v1_22/v8.go
+++ b/models/forgejo_migrations/v1_22/v8.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"strings"
diff --git a/models/forgejo_migrations/v1_22/v8_test.go b/models/forgejo_migrations/v1_22/v8_test.go
index baaba7290f..5117dd2dfb 100644
--- a/models/forgejo_migrations/v1_22/v8_test.go
+++ b/models/forgejo_migrations/v1_22/v8_test.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"testing"
diff --git a/models/forgejo_migrations/v1_22/v9.go b/models/forgejo_migrations/v1_22/v9.go
index 34c2844c39..e3cdea97f2 100644
--- a/models/forgejo_migrations/v1_22/v9.go
+++ b/models/forgejo_migrations/v1_22/v9.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v20.go b/models/forgejo_migrations/v20.go
index 8ca9e91f73..91c7b8e911 100644
--- a/models/forgejo_migrations/v20.go
+++ b/models/forgejo_migrations/v20.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v21.go b/models/forgejo_migrations/v21.go
index 53f141b2ab..61d7950c5a 100644
--- a/models/forgejo_migrations/v21.go
+++ b/models/forgejo_migrations/v21.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v22.go b/models/forgejo_migrations/v22.go
index eeb738799c..8078591da6 100644
--- a/models/forgejo_migrations/v22.go
+++ b/models/forgejo_migrations/v22.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v23.go b/models/forgejo_migrations/v23.go
index 20a916a716..a79a4f3d6e 100644
--- a/models/forgejo_migrations/v23.go
+++ b/models/forgejo_migrations/v23.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v24.go b/models/forgejo_migrations/v24.go
index ebfb5fc1c4..084a57e1ce 100644
--- a/models/forgejo_migrations/v24.go
+++ b/models/forgejo_migrations/v24.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v25.go b/models/forgejo_migrations/v25.go
index 8e3032a40c..56cde499a3 100644
--- a/models/forgejo_migrations/v25.go
+++ b/models/forgejo_migrations/v25.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"context"
diff --git a/models/forgejo_migrations/v25_test.go b/models/forgejo_migrations/v25_test.go
index e7402fd021..68e71da012 100644
--- a/models/forgejo_migrations/v25_test.go
+++ b/models/forgejo_migrations/v25_test.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"testing"
diff --git a/models/forgejo_migrations/v26.go b/models/forgejo_migrations/v26.go
index 3292d93ffd..a0c47799c2 100644
--- a/models/forgejo_migrations/v26.go
+++ b/models/forgejo_migrations/v26.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v27.go b/models/forgejo_migrations/v27.go
index 2efa3485a8..9cfbc64370 100644
--- a/models/forgejo_migrations/v27.go
+++ b/models/forgejo_migrations/v27.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"forgejo.org/modules/timeutil"
diff --git a/models/forgejo_migrations/v28.go b/models/forgejo_migrations/v28.go
index cba888d2ec..19f0dcd862 100644
--- a/models/forgejo_migrations/v28.go
+++ b/models/forgejo_migrations/v28.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v29.go b/models/forgejo_migrations/v29.go
index d0c2f723ae..92eb05e8b3 100644
--- a/models/forgejo_migrations/v29.go
+++ b/models/forgejo_migrations/v29.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"database/sql"
diff --git a/models/forgejo_migrations/v30.go b/models/forgejo_migrations/v30.go
index 6c41a55316..05a1dff898 100644
--- a/models/forgejo_migrations/v30.go
+++ b/models/forgejo_migrations/v30.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"time"
diff --git a/models/forgejo_migrations/v30_test.go b/models/forgejo_migrations/v30_test.go
index f826dab815..152fddeb47 100644
--- a/models/forgejo_migrations/v30_test.go
+++ b/models/forgejo_migrations/v30_test.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors.
// SPDX-License-Identifier: GPL-3.0-or-later
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"testing"
diff --git a/models/forgejo_migrations/v31.go b/models/forgejo_migrations/v31.go
index fdcab21b1a..23397c7c13 100644
--- a/models/forgejo_migrations/v31.go
+++ b/models/forgejo_migrations/v31.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors.
// SPDX-License-Identifier: GPL-3.0-or-later
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"xorm.io/xorm"
diff --git a/models/forgejo_migrations/v31_test.go b/models/forgejo_migrations/v31_test.go
index 5b4aac2a60..6d1690aae0 100644
--- a/models/forgejo_migrations/v31_test.go
+++ b/models/forgejo_migrations/v31_test.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors.
// SPDX-License-Identifier: GPL-3.0-or-later
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"testing"
diff --git a/models/forgejo_migrations/v32.go b/models/forgejo_migrations/v32.go
index bed335ab6b..81b22c585c 100644
--- a/models/forgejo_migrations/v32.go
+++ b/models/forgejo_migrations/v32.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"encoding/xml"
diff --git a/models/forgejo_migrations/v32_test.go b/models/forgejo_migrations/v32_test.go
index cd33de2608..24cda891bc 100644
--- a/models/forgejo_migrations/v32_test.go
+++ b/models/forgejo_migrations/v32_test.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"bytes"
diff --git a/models/forgejo_migrations/v33.go b/models/forgejo_migrations/v33.go
index 272035fc23..b9ea8efe47 100644
--- a/models/forgejo_migrations/v33.go
+++ b/models/forgejo_migrations/v33.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"fmt"
diff --git a/models/forgejo_migrations/v33_test.go b/models/forgejo_migrations/v33_test.go
index 664c704bbc..1d3298da15 100644
--- a/models/forgejo_migrations/v33_test.go
+++ b/models/forgejo_migrations/v33_test.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors.
// SPDX-License-Identifier: GPL-3.0-or-later
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
"testing"
diff --git a/models/forgejo_migrations/v34.go b/models/forgejo_migrations/v34.go
index 9e958b934f..d193d799e7 100644
--- a/models/forgejo_migrations/v34.go
+++ b/models/forgejo_migrations/v34.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import "xorm.io/xorm"
diff --git a/models/forgejo_migrations/v35.go b/models/forgejo_migrations/v35.go
index 0fb3b43e2c..9b389fcc12 100644
--- a/models/forgejo_migrations/v35.go
+++ b/models/forgejo_migrations/v35.go
@@ -1,19 +1,13 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
-package forgejo_migrations //nolint:revive
+package forgejo_migrations
import (
- "forgejo.org/modules/timeutil"
-
"xorm.io/xorm"
)
-func AddIndexToActionRunStopped(x *xorm.Engine) error {
- type ActionRun struct {
- ID int64
- Stopped timeutil.TimeStamp `xorm:"index"`
- }
-
- return x.Sync(&ActionRun{})
+// see https://codeberg.org/forgejo/forgejo/issues/8373
+func NoopAddIndexToActionRunStopped(x *xorm.Engine) error {
+ return nil
}
diff --git a/models/forgejo_migrations/v36.go b/models/forgejo_migrations/v36.go
new file mode 100644
index 0000000000..1a798147cf
--- /dev/null
+++ b/models/forgejo_migrations/v36.go
@@ -0,0 +1,55 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package forgejo_migrations
+
+import (
+ "xorm.io/xorm"
+)
+
+func FixWikiUnitDefaultPermission(x *xorm.Engine) error {
+ // Type is Unit's Type
+ type Type int
+
+ // Enumerate all the unit types
+ const (
+ TypeInvalid Type = iota // 0 invalid
+ TypeCode // 1 code
+ TypeIssues // 2 issues
+ TypePullRequests // 3 PRs
+ TypeReleases // 4 Releases
+ TypeWiki // 5 Wiki
+ TypeExternalWiki // 6 ExternalWiki
+ TypeExternalTracker // 7 ExternalTracker
+ TypeProjects // 8 Projects
+ TypePackages // 9 Packages
+ TypeActions // 10 Actions
+ )
+
+ // RepoUnitAccessMode specifies the users access mode to a repo unit
+ type UnitAccessMode int
+
+ const (
+ // UnitAccessModeUnset - no unit mode set
+ UnitAccessModeUnset UnitAccessMode = iota // 0
+ // UnitAccessModeNone no access
+ UnitAccessModeNone // 1
+ // UnitAccessModeRead read access
+ UnitAccessModeRead // 2
+ // UnitAccessModeWrite write access
+ UnitAccessModeWrite // 3
+ )
+ _ = UnitAccessModeNone
+ _ = UnitAccessModeWrite
+
+ type RepoUnit struct {
+ DefaultPermissions UnitAccessMode `xorm:"NOT NULL DEFAULT 0"`
+ }
+ _, err := x.Where("type = ?", TypeWiki).
+ Where("default_permissions = ?", UnitAccessModeRead).
+ Cols("default_permissions").
+ Update(RepoUnit{
+ DefaultPermissions: UnitAccessModeUnset,
+ })
+ return err
+}
diff --git a/models/migrations/test/tests.go b/models/migrations/test/tests.go
index c1f0caf19b..6be3b3c2fc 100644
--- a/models/migrations/test/tests.go
+++ b/models/migrations/test/tests.go
@@ -95,7 +95,8 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, fu
t.Logf("initializing fixtures from: %s", fixturesDir)
if err := unittest.InitFixtures(
unittest.FixturesOptions{
- Dir: fixturesDir,
+ Dir: fixturesDir,
+ SkipCleanRegistedModels: true,
}, x); err != nil {
t.Errorf("error whilst initializing fixtures from %s: %v", fixturesDir, err)
return x, deferFn
diff --git a/models/migrations/v1_10/v100.go b/models/migrations/v1_10/v100.go
index 5d2fd8e244..1742bea296 100644
--- a/models/migrations/v1_10/v100.go
+++ b/models/migrations/v1_10/v100.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import (
"net/url"
diff --git a/models/migrations/v1_10/v101.go b/models/migrations/v1_10/v101.go
index f023a2a0e7..6c8dfe2486 100644
--- a/models/migrations/v1_10/v101.go
+++ b/models/migrations/v1_10/v101.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_10/v88.go b/models/migrations/v1_10/v88.go
index 7e86ac364f..eb8e81c19e 100644
--- a/models/migrations/v1_10/v88.go
+++ b/models/migrations/v1_10/v88.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import (
"crypto/sha1"
diff --git a/models/migrations/v1_10/v89.go b/models/migrations/v1_10/v89.go
index d5f27ffdc6..0df2a6e17b 100644
--- a/models/migrations/v1_10/v89.go
+++ b/models/migrations/v1_10/v89.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import "xorm.io/xorm"
diff --git a/models/migrations/v1_10/v90.go b/models/migrations/v1_10/v90.go
index 295d4b1c1b..5521a97e32 100644
--- a/models/migrations/v1_10/v90.go
+++ b/models/migrations/v1_10/v90.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import "xorm.io/xorm"
diff --git a/models/migrations/v1_10/v91.go b/models/migrations/v1_10/v91.go
index 48cac2de70..08db6c2742 100644
--- a/models/migrations/v1_10/v91.go
+++ b/models/migrations/v1_10/v91.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import "xorm.io/xorm"
diff --git a/models/migrations/v1_10/v92.go b/models/migrations/v1_10/v92.go
index 9080108594..b6c04a9234 100644
--- a/models/migrations/v1_10/v92.go
+++ b/models/migrations/v1_10/v92.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import (
"xorm.io/builder"
diff --git a/models/migrations/v1_10/v93.go b/models/migrations/v1_10/v93.go
index ee59a8db39..c131be9a8d 100644
--- a/models/migrations/v1_10/v93.go
+++ b/models/migrations/v1_10/v93.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import "xorm.io/xorm"
diff --git a/models/migrations/v1_10/v94.go b/models/migrations/v1_10/v94.go
index c131af162b..13b7d7b303 100644
--- a/models/migrations/v1_10/v94.go
+++ b/models/migrations/v1_10/v94.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import "xorm.io/xorm"
diff --git a/models/migrations/v1_10/v95.go b/models/migrations/v1_10/v95.go
index 3b1f67fd9c..86b52026bf 100644
--- a/models/migrations/v1_10/v95.go
+++ b/models/migrations/v1_10/v95.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import "xorm.io/xorm"
diff --git a/models/migrations/v1_10/v96.go b/models/migrations/v1_10/v96.go
index 3bfb770f24..bcbd618b49 100644
--- a/models/migrations/v1_10/v96.go
+++ b/models/migrations/v1_10/v96.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import (
"path/filepath"
diff --git a/models/migrations/v1_10/v97.go b/models/migrations/v1_10/v97.go
index dee45b32e3..5872bb63e5 100644
--- a/models/migrations/v1_10/v97.go
+++ b/models/migrations/v1_10/v97.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import "xorm.io/xorm"
diff --git a/models/migrations/v1_10/v98.go b/models/migrations/v1_10/v98.go
index bdd9aed089..d21c326459 100644
--- a/models/migrations/v1_10/v98.go
+++ b/models/migrations/v1_10/v98.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import "xorm.io/xorm"
diff --git a/models/migrations/v1_10/v99.go b/models/migrations/v1_10/v99.go
index 7f287b77aa..addae66be9 100644
--- a/models/migrations/v1_10/v99.go
+++ b/models/migrations/v1_10/v99.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_10 //nolint
+package v1_10
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_11/v102.go b/models/migrations/v1_11/v102.go
index a585d9c423..15f0c83c36 100644
--- a/models/migrations/v1_11/v102.go
+++ b/models/migrations/v1_11/v102.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_11/v103.go b/models/migrations/v1_11/v103.go
index 53527dac58..a515710160 100644
--- a/models/migrations/v1_11/v103.go
+++ b/models/migrations/v1_11/v103.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_11/v104.go b/models/migrations/v1_11/v104.go
index af3578ca4a..7461f0cda3 100644
--- a/models/migrations/v1_11/v104.go
+++ b/models/migrations/v1_11/v104.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_11/v105.go b/models/migrations/v1_11/v105.go
index b91340c30a..d86973a0f6 100644
--- a/models/migrations/v1_11/v105.go
+++ b/models/migrations/v1_11/v105.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_11/v106.go b/models/migrations/v1_11/v106.go
index ecb11cdd1e..edffe18683 100644
--- a/models/migrations/v1_11/v106.go
+++ b/models/migrations/v1_11/v106.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_11/v107.go b/models/migrations/v1_11/v107.go
index f0bfe5862c..a158e3bb50 100644
--- a/models/migrations/v1_11/v107.go
+++ b/models/migrations/v1_11/v107.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_11/v108.go b/models/migrations/v1_11/v108.go
index a85096234d..8f14504ceb 100644
--- a/models/migrations/v1_11/v108.go
+++ b/models/migrations/v1_11/v108.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_11/v109.go b/models/migrations/v1_11/v109.go
index ea565ccda3..f7616aec7b 100644
--- a/models/migrations/v1_11/v109.go
+++ b/models/migrations/v1_11/v109.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_11/v110.go b/models/migrations/v1_11/v110.go
index fce9be847e..e94a738f67 100644
--- a/models/migrations/v1_11/v110.go
+++ b/models/migrations/v1_11/v110.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_11/v111.go b/models/migrations/v1_11/v111.go
index cc3dc0d545..6f531e4858 100644
--- a/models/migrations/v1_11/v111.go
+++ b/models/migrations/v1_11/v111.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"fmt"
diff --git a/models/migrations/v1_11/v112.go b/models/migrations/v1_11/v112.go
index 6112ab51a5..22054e6f68 100644
--- a/models/migrations/v1_11/v112.go
+++ b/models/migrations/v1_11/v112.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"fmt"
diff --git a/models/migrations/v1_11/v113.go b/models/migrations/v1_11/v113.go
index dea344a44f..a4d54f66fb 100644
--- a/models/migrations/v1_11/v113.go
+++ b/models/migrations/v1_11/v113.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"fmt"
diff --git a/models/migrations/v1_11/v114.go b/models/migrations/v1_11/v114.go
index 95adcee989..9467a8a90c 100644
--- a/models/migrations/v1_11/v114.go
+++ b/models/migrations/v1_11/v114.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"net/url"
diff --git a/models/migrations/v1_11/v115.go b/models/migrations/v1_11/v115.go
index 3d4b41017b..65094df93d 100644
--- a/models/migrations/v1_11/v115.go
+++ b/models/migrations/v1_11/v115.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"crypto/md5"
diff --git a/models/migrations/v1_11/v116.go b/models/migrations/v1_11/v116.go
index 85aa76c1e0..729fbad18b 100644
--- a/models/migrations/v1_11/v116.go
+++ b/models/migrations/v1_11/v116.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_11 //nolint
+package v1_11
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_12/v117.go b/models/migrations/v1_12/v117.go
index 8eadcdef2b..73b58ca34b 100644
--- a/models/migrations/v1_12/v117.go
+++ b/models/migrations/v1_12/v117.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_12/v118.go b/models/migrations/v1_12/v118.go
index eb022dc5e4..e8b4249743 100644
--- a/models/migrations/v1_12/v118.go
+++ b/models/migrations/v1_12/v118.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_12/v119.go b/models/migrations/v1_12/v119.go
index 60bfe6a57d..b4bf29a935 100644
--- a/models/migrations/v1_12/v119.go
+++ b/models/migrations/v1_12/v119.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_12/v120.go b/models/migrations/v1_12/v120.go
index 3f7ed8d373..14d515f5a7 100644
--- a/models/migrations/v1_12/v120.go
+++ b/models/migrations/v1_12/v120.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_12/v121.go b/models/migrations/v1_12/v121.go
index 175ec9164d..a28ae4e1c9 100644
--- a/models/migrations/v1_12/v121.go
+++ b/models/migrations/v1_12/v121.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import "xorm.io/xorm"
diff --git a/models/migrations/v1_12/v122.go b/models/migrations/v1_12/v122.go
index 6e31d863a1..bc1b175f6a 100644
--- a/models/migrations/v1_12/v122.go
+++ b/models/migrations/v1_12/v122.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_12/v123.go b/models/migrations/v1_12/v123.go
index b0c3af07a3..52b10bb850 100644
--- a/models/migrations/v1_12/v123.go
+++ b/models/migrations/v1_12/v123.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_12/v124.go b/models/migrations/v1_12/v124.go
index d2ba03ffe0..9a93f436d4 100644
--- a/models/migrations/v1_12/v124.go
+++ b/models/migrations/v1_12/v124.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_12/v125.go b/models/migrations/v1_12/v125.go
index ec4ffaab25..7f582ecff5 100644
--- a/models/migrations/v1_12/v125.go
+++ b/models/migrations/v1_12/v125.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"fmt"
diff --git a/models/migrations/v1_12/v126.go b/models/migrations/v1_12/v126.go
index ca9ec3aa3f..64fd7f7478 100644
--- a/models/migrations/v1_12/v126.go
+++ b/models/migrations/v1_12/v126.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"xorm.io/builder"
diff --git a/models/migrations/v1_12/v127.go b/models/migrations/v1_12/v127.go
index 11a4042973..f686fa617c 100644
--- a/models/migrations/v1_12/v127.go
+++ b/models/migrations/v1_12/v127.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"fmt"
diff --git a/models/migrations/v1_12/v128.go b/models/migrations/v1_12/v128.go
index 6d7307f470..8fca974616 100644
--- a/models/migrations/v1_12/v128.go
+++ b/models/migrations/v1_12/v128.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"fmt"
diff --git a/models/migrations/v1_12/v129.go b/models/migrations/v1_12/v129.go
index cf228242b9..3e4d3aca68 100644
--- a/models/migrations/v1_12/v129.go
+++ b/models/migrations/v1_12/v129.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_12/v130.go b/models/migrations/v1_12/v130.go
index bfa856796a..383ef47492 100644
--- a/models/migrations/v1_12/v130.go
+++ b/models/migrations/v1_12/v130.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"forgejo.org/modules/json"
diff --git a/models/migrations/v1_12/v131.go b/models/migrations/v1_12/v131.go
index 5184bc3590..1266c2f185 100644
--- a/models/migrations/v1_12/v131.go
+++ b/models/migrations/v1_12/v131.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"fmt"
diff --git a/models/migrations/v1_12/v132.go b/models/migrations/v1_12/v132.go
index 3b2b28f7ab..8b1ae6db93 100644
--- a/models/migrations/v1_12/v132.go
+++ b/models/migrations/v1_12/v132.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"fmt"
diff --git a/models/migrations/v1_12/v133.go b/models/migrations/v1_12/v133.go
index c9087fc8c1..69e20597d8 100644
--- a/models/migrations/v1_12/v133.go
+++ b/models/migrations/v1_12/v133.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import "xorm.io/xorm"
diff --git a/models/migrations/v1_12/v134.go b/models/migrations/v1_12/v134.go
index bba996fd40..1fabdcae96 100644
--- a/models/migrations/v1_12/v134.go
+++ b/models/migrations/v1_12/v134.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"fmt"
diff --git a/models/migrations/v1_12/v135.go b/models/migrations/v1_12/v135.go
index 8898011df5..5df0ad7fc4 100644
--- a/models/migrations/v1_12/v135.go
+++ b/models/migrations/v1_12/v135.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"fmt"
diff --git a/models/migrations/v1_12/v136.go b/models/migrations/v1_12/v136.go
index e2557ae002..7d246a82be 100644
--- a/models/migrations/v1_12/v136.go
+++ b/models/migrations/v1_12/v136.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"fmt"
diff --git a/models/migrations/v1_12/v137.go b/models/migrations/v1_12/v137.go
index 0d86b72010..9d38483488 100644
--- a/models/migrations/v1_12/v137.go
+++ b/models/migrations/v1_12/v137.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_12/v138.go b/models/migrations/v1_12/v138.go
index 8c8d353f40..4485adeb2d 100644
--- a/models/migrations/v1_12/v138.go
+++ b/models/migrations/v1_12/v138.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"fmt"
diff --git a/models/migrations/v1_12/v139.go b/models/migrations/v1_12/v139.go
index cd7963524e..51e57b984a 100644
--- a/models/migrations/v1_12/v139.go
+++ b/models/migrations/v1_12/v139.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_12 //nolint
+package v1_12
import (
"forgejo.org/modules/setting"
diff --git a/models/migrations/v1_13/v140.go b/models/migrations/v1_13/v140.go
index d74f808e9f..5bb612c098 100644
--- a/models/migrations/v1_13/v140.go
+++ b/models/migrations/v1_13/v140.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"fmt"
diff --git a/models/migrations/v1_13/v141.go b/models/migrations/v1_13/v141.go
index ae211e0e44..b54bc1727c 100644
--- a/models/migrations/v1_13/v141.go
+++ b/models/migrations/v1_13/v141.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"fmt"
diff --git a/models/migrations/v1_13/v142.go b/models/migrations/v1_13/v142.go
index 7490e0f3b4..8939f6f2f8 100644
--- a/models/migrations/v1_13/v142.go
+++ b/models/migrations/v1_13/v142.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"forgejo.org/modules/log"
diff --git a/models/migrations/v1_13/v143.go b/models/migrations/v1_13/v143.go
index 1f9120e2ba..6a8da8b06d 100644
--- a/models/migrations/v1_13/v143.go
+++ b/models/migrations/v1_13/v143.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"forgejo.org/modules/log"
diff --git a/models/migrations/v1_13/v144.go b/models/migrations/v1_13/v144.go
index 7e801eab8a..f138338514 100644
--- a/models/migrations/v1_13/v144.go
+++ b/models/migrations/v1_13/v144.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"forgejo.org/modules/log"
diff --git a/models/migrations/v1_13/v145.go b/models/migrations/v1_13/v145.go
index a01f577ed1..f7d3895c84 100644
--- a/models/migrations/v1_13/v145.go
+++ b/models/migrations/v1_13/v145.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"fmt"
diff --git a/models/migrations/v1_13/v146.go b/models/migrations/v1_13/v146.go
index a1b54ee3aa..e6a476a288 100644
--- a/models/migrations/v1_13/v146.go
+++ b/models/migrations/v1_13/v146.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_13/v147.go b/models/migrations/v1_13/v147.go
index cc57504c74..831ef5842a 100644
--- a/models/migrations/v1_13/v147.go
+++ b/models/migrations/v1_13/v147.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_13/v148.go b/models/migrations/v1_13/v148.go
index 7bb8ab700b..d276db3d61 100644
--- a/models/migrations/v1_13/v148.go
+++ b/models/migrations/v1_13/v148.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_13/v149.go b/models/migrations/v1_13/v149.go
index 3a0c5909d5..c1bfe8b09e 100644
--- a/models/migrations/v1_13/v149.go
+++ b/models/migrations/v1_13/v149.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"fmt"
diff --git a/models/migrations/v1_13/v150.go b/models/migrations/v1_13/v150.go
index be14fd130c..471a531024 100644
--- a/models/migrations/v1_13/v150.go
+++ b/models/migrations/v1_13/v150.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_13/v151.go b/models/migrations/v1_13/v151.go
index ff584fff67..691b86062d 100644
--- a/models/migrations/v1_13/v151.go
+++ b/models/migrations/v1_13/v151.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"context"
diff --git a/models/migrations/v1_13/v152.go b/models/migrations/v1_13/v152.go
index 502c82a40d..648e26446f 100644
--- a/models/migrations/v1_13/v152.go
+++ b/models/migrations/v1_13/v152.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import "xorm.io/xorm"
diff --git a/models/migrations/v1_13/v153.go b/models/migrations/v1_13/v153.go
index 0b2dd3eb62..e5462fc162 100644
--- a/models/migrations/v1_13/v153.go
+++ b/models/migrations/v1_13/v153.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_13/v154.go b/models/migrations/v1_13/v154.go
index cf31190781..89dc7821b2 100644
--- a/models/migrations/v1_13/v154.go
+++ b/models/migrations/v1_13/v154.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_13 //nolint
+package v1_13
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_14/main_test.go b/models/migrations/v1_14/main_test.go
index c01faedc35..57cf995be1 100644
--- a/models/migrations/v1_14/main_test.go
+++ b/models/migrations/v1_14/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"testing"
diff --git a/models/migrations/v1_14/v155.go b/models/migrations/v1_14/v155.go
index e814f59938..505a9ae033 100644
--- a/models/migrations/v1_14/v155.go
+++ b/models/migrations/v1_14/v155.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"fmt"
diff --git a/models/migrations/v1_14/v156.go b/models/migrations/v1_14/v156.go
index b6dc91a054..7bbd9f4c85 100644
--- a/models/migrations/v1_14/v156.go
+++ b/models/migrations/v1_14/v156.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"fmt"
diff --git a/models/migrations/v1_14/v157.go b/models/migrations/v1_14/v157.go
index 7187278d29..ba69f71130 100644
--- a/models/migrations/v1_14/v157.go
+++ b/models/migrations/v1_14/v157.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_14/v158.go b/models/migrations/v1_14/v158.go
index 3fa27cfecd..2ab3c8a1f0 100644
--- a/models/migrations/v1_14/v158.go
+++ b/models/migrations/v1_14/v158.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"errors"
diff --git a/models/migrations/v1_14/v159.go b/models/migrations/v1_14/v159.go
index fdd7e12449..4e921ea1c6 100644
--- a/models/migrations/v1_14/v159.go
+++ b/models/migrations/v1_14/v159.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_14/v160.go b/models/migrations/v1_14/v160.go
index 4dea91b514..73f3798954 100644
--- a/models/migrations/v1_14/v160.go
+++ b/models/migrations/v1_14/v160.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_14/v161.go b/models/migrations/v1_14/v161.go
index 6e904cfab6..9c850ad0c2 100644
--- a/models/migrations/v1_14/v161.go
+++ b/models/migrations/v1_14/v161.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"context"
diff --git a/models/migrations/v1_14/v162.go b/models/migrations/v1_14/v162.go
index 5d6d7c2e3f..ead63f16f4 100644
--- a/models/migrations/v1_14/v162.go
+++ b/models/migrations/v1_14/v162.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_14/v163.go b/models/migrations/v1_14/v163.go
index 60fc98c0a4..06ac36cbc7 100644
--- a/models/migrations/v1_14/v163.go
+++ b/models/migrations/v1_14/v163.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_14/v164.go b/models/migrations/v1_14/v164.go
index 54f6951427..d2fd9b8464 100644
--- a/models/migrations/v1_14/v164.go
+++ b/models/migrations/v1_14/v164.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"fmt"
diff --git a/models/migrations/v1_14/v165.go b/models/migrations/v1_14/v165.go
index 9315e44197..90fd2b1e46 100644
--- a/models/migrations/v1_14/v165.go
+++ b/models/migrations/v1_14/v165.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_14/v166.go b/models/migrations/v1_14/v166.go
index e5731582fd..4c106bd7da 100644
--- a/models/migrations/v1_14/v166.go
+++ b/models/migrations/v1_14/v166.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"crypto/sha256"
diff --git a/models/migrations/v1_14/v167.go b/models/migrations/v1_14/v167.go
index 9d416f6a32..d77bbc401e 100644
--- a/models/migrations/v1_14/v167.go
+++ b/models/migrations/v1_14/v167.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"fmt"
diff --git a/models/migrations/v1_14/v168.go b/models/migrations/v1_14/v168.go
index a30a8859f7..aa93eec19b 100644
--- a/models/migrations/v1_14/v168.go
+++ b/models/migrations/v1_14/v168.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import "xorm.io/xorm"
diff --git a/models/migrations/v1_14/v169.go b/models/migrations/v1_14/v169.go
index 5b81bb58b1..4f9df0d96f 100644
--- a/models/migrations/v1_14/v169.go
+++ b/models/migrations/v1_14/v169.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_14/v170.go b/models/migrations/v1_14/v170.go
index 7b6498a3e9..a2ff4623e1 100644
--- a/models/migrations/v1_14/v170.go
+++ b/models/migrations/v1_14/v170.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"fmt"
diff --git a/models/migrations/v1_14/v171.go b/models/migrations/v1_14/v171.go
index 51a35a02ad..7b200e960a 100644
--- a/models/migrations/v1_14/v171.go
+++ b/models/migrations/v1_14/v171.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"fmt"
diff --git a/models/migrations/v1_14/v172.go b/models/migrations/v1_14/v172.go
index d49b70f5ad..c410d393f1 100644
--- a/models/migrations/v1_14/v172.go
+++ b/models/migrations/v1_14/v172.go
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_14/v173.go b/models/migrations/v1_14/v173.go
index 2d9eee9197..7752fbe966 100644
--- a/models/migrations/v1_14/v173.go
+++ b/models/migrations/v1_14/v173.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"fmt"
diff --git a/models/migrations/v1_14/v174.go b/models/migrations/v1_14/v174.go
index c839e15db8..4049e43070 100644
--- a/models/migrations/v1_14/v174.go
+++ b/models/migrations/v1_14/v174.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"fmt"
diff --git a/models/migrations/v1_14/v175.go b/models/migrations/v1_14/v175.go
index 3cda5772a0..49fa17d046 100644
--- a/models/migrations/v1_14/v175.go
+++ b/models/migrations/v1_14/v175.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"fmt"
diff --git a/models/migrations/v1_14/v176.go b/models/migrations/v1_14/v176.go
index 1ed49f75fa..ef5dce9a02 100644
--- a/models/migrations/v1_14/v176.go
+++ b/models/migrations/v1_14/v176.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_14/v176_test.go b/models/migrations/v1_14/v176_test.go
index d88ff207e7..d56b3e0470 100644
--- a/models/migrations/v1_14/v176_test.go
+++ b/models/migrations/v1_14/v176_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"testing"
diff --git a/models/migrations/v1_14/v177.go b/models/migrations/v1_14/v177.go
index 6e1838f369..96676bf8d9 100644
--- a/models/migrations/v1_14/v177.go
+++ b/models/migrations/v1_14/v177.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"fmt"
diff --git a/models/migrations/v1_14/v177_test.go b/models/migrations/v1_14/v177_test.go
index bffc6f92e3..0e0a67fd33 100644
--- a/models/migrations/v1_14/v177_test.go
+++ b/models/migrations/v1_14/v177_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_14 //nolint
+package v1_14
import (
"testing"
diff --git a/models/migrations/v1_15/main_test.go b/models/migrations/v1_15/main_test.go
index 6c04d3f5ee..4cf6d6f695 100644
--- a/models/migrations/v1_15/main_test.go
+++ b/models/migrations/v1_15/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"testing"
diff --git a/models/migrations/v1_15/v178.go b/models/migrations/v1_15/v178.go
index 6d236eb049..ca3a5c262e 100644
--- a/models/migrations/v1_15/v178.go
+++ b/models/migrations/v1_15/v178.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_15/v179.go b/models/migrations/v1_15/v179.go
index b990583303..ce514cc4a9 100644
--- a/models/migrations/v1_15/v179.go
+++ b/models/migrations/v1_15/v179.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_15/v180.go b/models/migrations/v1_15/v180.go
index 02fbd57cdb..0b68c3ceb7 100644
--- a/models/migrations/v1_15/v180.go
+++ b/models/migrations/v1_15/v180.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"forgejo.org/modules/json"
diff --git a/models/migrations/v1_15/v181.go b/models/migrations/v1_15/v181.go
index 2185ed0213..fb1d3d7a75 100644
--- a/models/migrations/v1_15/v181.go
+++ b/models/migrations/v1_15/v181.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"strings"
diff --git a/models/migrations/v1_15/v181_test.go b/models/migrations/v1_15/v181_test.go
index 4154e0b1e9..8196f751e5 100644
--- a/models/migrations/v1_15/v181_test.go
+++ b/models/migrations/v1_15/v181_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"strings"
diff --git a/models/migrations/v1_15/v182.go b/models/migrations/v1_15/v182.go
index 9ca500c0f9..f53ff11df9 100644
--- a/models/migrations/v1_15/v182.go
+++ b/models/migrations/v1_15/v182.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_15/v182_test.go b/models/migrations/v1_15/v182_test.go
index 6865cafac4..2baf90d06a 100644
--- a/models/migrations/v1_15/v182_test.go
+++ b/models/migrations/v1_15/v182_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"testing"
diff --git a/models/migrations/v1_15/v183.go b/models/migrations/v1_15/v183.go
index aaad64c220..5684e35699 100644
--- a/models/migrations/v1_15/v183.go
+++ b/models/migrations/v1_15/v183.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"fmt"
diff --git a/models/migrations/v1_15/v184.go b/models/migrations/v1_15/v184.go
index 41b64d4743..fbe0dcd780 100644
--- a/models/migrations/v1_15/v184.go
+++ b/models/migrations/v1_15/v184.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"context"
diff --git a/models/migrations/v1_15/v185.go b/models/migrations/v1_15/v185.go
index e5878ec193..60af59edca 100644
--- a/models/migrations/v1_15/v185.go
+++ b/models/migrations/v1_15/v185.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_15/v186.go b/models/migrations/v1_15/v186.go
index ad75822de5..55d3199335 100644
--- a/models/migrations/v1_15/v186.go
+++ b/models/migrations/v1_15/v186.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_15/v187.go b/models/migrations/v1_15/v187.go
index b573fc52ef..fabef14779 100644
--- a/models/migrations/v1_15/v187.go
+++ b/models/migrations/v1_15/v187.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_15/v188.go b/models/migrations/v1_15/v188.go
index 71e45cab0e..4494e6ff05 100644
--- a/models/migrations/v1_15/v188.go
+++ b/models/migrations/v1_15/v188.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_15 //nolint
+package v1_15
import "xorm.io/xorm"
diff --git a/models/migrations/v1_16/main_test.go b/models/migrations/v1_16/main_test.go
index 6f891f3e94..8c0a043be6 100644
--- a/models/migrations/v1_16/main_test.go
+++ b/models/migrations/v1_16/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"testing"
diff --git a/models/migrations/v1_16/v189.go b/models/migrations/v1_16/v189.go
index 1ee72d9c39..19bfcb2423 100644
--- a/models/migrations/v1_16/v189.go
+++ b/models/migrations/v1_16/v189.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"encoding/binary"
diff --git a/models/migrations/v1_16/v189_test.go b/models/migrations/v1_16/v189_test.go
index 90b721d5f1..9d74462a92 100644
--- a/models/migrations/v1_16/v189_test.go
+++ b/models/migrations/v1_16/v189_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"testing"
diff --git a/models/migrations/v1_16/v190.go b/models/migrations/v1_16/v190.go
index 5953802849..1eb6b6ddb4 100644
--- a/models/migrations/v1_16/v190.go
+++ b/models/migrations/v1_16/v190.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"fmt"
diff --git a/models/migrations/v1_16/v191.go b/models/migrations/v1_16/v191.go
index 567f88d6d1..427476b70b 100644
--- a/models/migrations/v1_16/v191.go
+++ b/models/migrations/v1_16/v191.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"forgejo.org/modules/setting"
diff --git a/models/migrations/v1_16/v192.go b/models/migrations/v1_16/v192.go
index 731b9fb43a..31e8c36346 100644
--- a/models/migrations/v1_16/v192.go
+++ b/models/migrations/v1_16/v192.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_16/v193.go b/models/migrations/v1_16/v193.go
index 8d3ce7a558..a5af2de380 100644
--- a/models/migrations/v1_16/v193.go
+++ b/models/migrations/v1_16/v193.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_16/v193_test.go b/models/migrations/v1_16/v193_test.go
index 8260acf32d..bf8d8a7dc6 100644
--- a/models/migrations/v1_16/v193_test.go
+++ b/models/migrations/v1_16/v193_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"testing"
diff --git a/models/migrations/v1_16/v194.go b/models/migrations/v1_16/v194.go
index 6aa13c50cf..2e4ed8340e 100644
--- a/models/migrations/v1_16/v194.go
+++ b/models/migrations/v1_16/v194.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"fmt"
diff --git a/models/migrations/v1_16/v195.go b/models/migrations/v1_16/v195.go
index 6d7e94141e..4fd42b7bd2 100644
--- a/models/migrations/v1_16/v195.go
+++ b/models/migrations/v1_16/v195.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"fmt"
diff --git a/models/migrations/v1_16/v195_test.go b/models/migrations/v1_16/v195_test.go
index 71234a6fb3..1fc7b51f3c 100644
--- a/models/migrations/v1_16/v195_test.go
+++ b/models/migrations/v1_16/v195_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"testing"
diff --git a/models/migrations/v1_16/v196.go b/models/migrations/v1_16/v196.go
index 7cbafc61e5..6c9caa100f 100644
--- a/models/migrations/v1_16/v196.go
+++ b/models/migrations/v1_16/v196.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"fmt"
diff --git a/models/migrations/v1_16/v197.go b/models/migrations/v1_16/v197.go
index 97888b2847..862bdfdcbd 100644
--- a/models/migrations/v1_16/v197.go
+++ b/models/migrations/v1_16/v197.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_16/v198.go b/models/migrations/v1_16/v198.go
index 8b3c73addc..5d3043eb46 100644
--- a/models/migrations/v1_16/v198.go
+++ b/models/migrations/v1_16/v198.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"fmt"
diff --git a/models/migrations/v1_16/v199.go b/models/migrations/v1_16/v199.go
index 6adcf890af..4020352f2b 100644
--- a/models/migrations/v1_16/v199.go
+++ b/models/migrations/v1_16/v199.go
@@ -1,6 +1,6 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
// We used to use a table `remote_version` to store information for updater, now we use `AppState`, so this migration task is a no-op now.
diff --git a/models/migrations/v1_16/v200.go b/models/migrations/v1_16/v200.go
index c08c20e51d..de57fad8fe 100644
--- a/models/migrations/v1_16/v200.go
+++ b/models/migrations/v1_16/v200.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"fmt"
diff --git a/models/migrations/v1_16/v201.go b/models/migrations/v1_16/v201.go
index 35e0c9f2fb..2c43698b0c 100644
--- a/models/migrations/v1_16/v201.go
+++ b/models/migrations/v1_16/v201.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_16/v202.go b/models/migrations/v1_16/v202.go
index 6ba36152f1..d8c8fdcadc 100644
--- a/models/migrations/v1_16/v202.go
+++ b/models/migrations/v1_16/v202.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"fmt"
diff --git a/models/migrations/v1_16/v203.go b/models/migrations/v1_16/v203.go
index e8e6b52453..c3241cba57 100644
--- a/models/migrations/v1_16/v203.go
+++ b/models/migrations/v1_16/v203.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_16/v204.go b/models/migrations/v1_16/v204.go
index ece03e1305..4d375307e7 100644
--- a/models/migrations/v1_16/v204.go
+++ b/models/migrations/v1_16/v204.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import "xorm.io/xorm"
diff --git a/models/migrations/v1_16/v205.go b/models/migrations/v1_16/v205.go
index a064b9830d..cb452dfd7f 100644
--- a/models/migrations/v1_16/v205.go
+++ b/models/migrations/v1_16/v205.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_16/v206.go b/models/migrations/v1_16/v206.go
index 581a7d76e9..01a9c386eb 100644
--- a/models/migrations/v1_16/v206.go
+++ b/models/migrations/v1_16/v206.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"fmt"
diff --git a/models/migrations/v1_16/v207.go b/models/migrations/v1_16/v207.go
index 91208f066c..19126ead1f 100644
--- a/models/migrations/v1_16/v207.go
+++ b/models/migrations/v1_16/v207.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_16/v208.go b/models/migrations/v1_16/v208.go
index 1a11ef096a..fb643324f4 100644
--- a/models/migrations/v1_16/v208.go
+++ b/models/migrations/v1_16/v208.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_16/v209.go b/models/migrations/v1_16/v209.go
index be3100e02a..230838647b 100644
--- a/models/migrations/v1_16/v209.go
+++ b/models/migrations/v1_16/v209.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_16/v210.go b/models/migrations/v1_16/v210.go
index 375a008e18..f48ab11db6 100644
--- a/models/migrations/v1_16/v210.go
+++ b/models/migrations/v1_16/v210.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"crypto/ecdh"
diff --git a/models/migrations/v1_16/v210_test.go b/models/migrations/v1_16/v210_test.go
index f6423a5821..8454920aa0 100644
--- a/models/migrations/v1_16/v210_test.go
+++ b/models/migrations/v1_16/v210_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_16 //nolint
+package v1_16
import (
"encoding/hex"
diff --git a/models/migrations/v1_17/main_test.go b/models/migrations/v1_17/main_test.go
index 0a8e05ab5f..166860b3b1 100644
--- a/models/migrations/v1_17/main_test.go
+++ b/models/migrations/v1_17/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"testing"
diff --git a/models/migrations/v1_17/v211.go b/models/migrations/v1_17/v211.go
index 9b72c8610b..517cf19388 100644
--- a/models/migrations/v1_17/v211.go
+++ b/models/migrations/v1_17/v211.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_17/v212.go b/models/migrations/v1_17/v212.go
index 2337adcc80..23868c0bb2 100644
--- a/models/migrations/v1_17/v212.go
+++ b/models/migrations/v1_17/v212.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_17/v213.go b/models/migrations/v1_17/v213.go
index bb3f466e52..b2bbdf7279 100644
--- a/models/migrations/v1_17/v213.go
+++ b/models/migrations/v1_17/v213.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_17/v214.go b/models/migrations/v1_17/v214.go
index 2268164919..1925324f0f 100644
--- a/models/migrations/v1_17/v214.go
+++ b/models/migrations/v1_17/v214.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_17/v215.go b/models/migrations/v1_17/v215.go
index 5aae798562..431103c98e 100644
--- a/models/migrations/v1_17/v215.go
+++ b/models/migrations/v1_17/v215.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"forgejo.org/models/pull"
diff --git a/models/migrations/v1_17/v216.go b/models/migrations/v1_17/v216.go
index 268f472a42..37aeacb6fc 100644
--- a/models/migrations/v1_17/v216.go
+++ b/models/migrations/v1_17/v216.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
// This migration added non-ideal indices to the action table which on larger datasets slowed things down
// it has been superseded by v218.go
diff --git a/models/migrations/v1_17/v217.go b/models/migrations/v1_17/v217.go
index 5f096d4824..fef48b7a5b 100644
--- a/models/migrations/v1_17/v217.go
+++ b/models/migrations/v1_17/v217.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"forgejo.org/modules/setting"
diff --git a/models/migrations/v1_17/v218.go b/models/migrations/v1_17/v218.go
index 5e3dcd0841..412d124286 100644
--- a/models/migrations/v1_17/v218.go
+++ b/models/migrations/v1_17/v218.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"forgejo.org/modules/setting"
diff --git a/models/migrations/v1_17/v219.go b/models/migrations/v1_17/v219.go
index e90656090f..7ca6a26be6 100644
--- a/models/migrations/v1_17/v219.go
+++ b/models/migrations/v1_17/v219.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"time"
diff --git a/models/migrations/v1_17/v220.go b/models/migrations/v1_17/v220.go
index 61bbf19725..4e010e5b76 100644
--- a/models/migrations/v1_17/v220.go
+++ b/models/migrations/v1_17/v220.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
packages_model "forgejo.org/models/packages"
diff --git a/models/migrations/v1_17/v221.go b/models/migrations/v1_17/v221.go
index 84e9a238af..3ef34e3f06 100644
--- a/models/migrations/v1_17/v221.go
+++ b/models/migrations/v1_17/v221.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"encoding/base32"
diff --git a/models/migrations/v1_17/v221_test.go b/models/migrations/v1_17/v221_test.go
index 02607d6b32..a9c47136b2 100644
--- a/models/migrations/v1_17/v221_test.go
+++ b/models/migrations/v1_17/v221_test.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"encoding/base32"
diff --git a/models/migrations/v1_17/v222.go b/models/migrations/v1_17/v222.go
index ae910cbcb6..873769881e 100644
--- a/models/migrations/v1_17/v222.go
+++ b/models/migrations/v1_17/v222.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"context"
diff --git a/models/migrations/v1_17/v223.go b/models/migrations/v1_17/v223.go
index 7d92dcf5ae..4f5d34d841 100644
--- a/models/migrations/v1_17/v223.go
+++ b/models/migrations/v1_17/v223.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_17 //nolint
+package v1_17
import (
"context"
diff --git a/models/migrations/v1_18/main_test.go b/models/migrations/v1_18/main_test.go
index 33f5c51222..0c20934cea 100644
--- a/models/migrations/v1_18/main_test.go
+++ b/models/migrations/v1_18/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_18 //nolint
+package v1_18
import (
"testing"
diff --git a/models/migrations/v1_18/v224.go b/models/migrations/v1_18/v224.go
index f3d522b91a..6dc12020ea 100644
--- a/models/migrations/v1_18/v224.go
+++ b/models/migrations/v1_18/v224.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_18 //nolint
+package v1_18
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_18/v225.go b/models/migrations/v1_18/v225.go
index 86bcb1323d..266eccfff8 100644
--- a/models/migrations/v1_18/v225.go
+++ b/models/migrations/v1_18/v225.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_18 //nolint
+package v1_18
import (
"forgejo.org/modules/setting"
diff --git a/models/migrations/v1_18/v226.go b/models/migrations/v1_18/v226.go
index f87e24b11d..8ed9761476 100644
--- a/models/migrations/v1_18/v226.go
+++ b/models/migrations/v1_18/v226.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_18 //nolint
+package v1_18
import (
"xorm.io/builder"
diff --git a/models/migrations/v1_18/v227.go b/models/migrations/v1_18/v227.go
index b6250fb76c..d39a010159 100644
--- a/models/migrations/v1_18/v227.go
+++ b/models/migrations/v1_18/v227.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_18 //nolint
+package v1_18
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_18/v228.go b/models/migrations/v1_18/v228.go
index 1161c8a4c9..3f5b69734d 100644
--- a/models/migrations/v1_18/v228.go
+++ b/models/migrations/v1_18/v228.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_18 //nolint
+package v1_18
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_18/v229.go b/models/migrations/v1_18/v229.go
index f96dde9840..00d794725f 100644
--- a/models/migrations/v1_18/v229.go
+++ b/models/migrations/v1_18/v229.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_18 //nolint
+package v1_18
import (
"fmt"
diff --git a/models/migrations/v1_18/v229_test.go b/models/migrations/v1_18/v229_test.go
index ac5e726a79..903a60c851 100644
--- a/models/migrations/v1_18/v229_test.go
+++ b/models/migrations/v1_18/v229_test.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_18 //nolint
+package v1_18
import (
"testing"
diff --git a/models/migrations/v1_18/v230.go b/models/migrations/v1_18/v230.go
index ea5b4d02e1..078fce7643 100644
--- a/models/migrations/v1_18/v230.go
+++ b/models/migrations/v1_18/v230.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_18 //nolint
+package v1_18
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_18/v230_test.go b/models/migrations/v1_18/v230_test.go
index 7dd6675673..da31b0dc9b 100644
--- a/models/migrations/v1_18/v230_test.go
+++ b/models/migrations/v1_18/v230_test.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_18 //nolint
+package v1_18
import (
"testing"
diff --git a/models/migrations/v1_19/main_test.go b/models/migrations/v1_19/main_test.go
index 7c56926f4c..9d1c3a57ea 100644
--- a/models/migrations/v1_19/main_test.go
+++ b/models/migrations/v1_19/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"testing"
diff --git a/models/migrations/v1_19/v231.go b/models/migrations/v1_19/v231.go
index 79e46132f0..8ef1e4e743 100644
--- a/models/migrations/v1_19/v231.go
+++ b/models/migrations/v1_19/v231.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_19/v232.go b/models/migrations/v1_19/v232.go
index 7fb4a5ac8d..2aab2cf830 100644
--- a/models/migrations/v1_19/v232.go
+++ b/models/migrations/v1_19/v232.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"forgejo.org/modules/setting"
diff --git a/models/migrations/v1_19/v233.go b/models/migrations/v1_19/v233.go
index 191afd4868..e62e8a9356 100644
--- a/models/migrations/v1_19/v233.go
+++ b/models/migrations/v1_19/v233.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"fmt"
diff --git a/models/migrations/v1_19/v233_test.go b/models/migrations/v1_19/v233_test.go
index 4dc35d1e27..3d5eac9887 100644
--- a/models/migrations/v1_19/v233_test.go
+++ b/models/migrations/v1_19/v233_test.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"testing"
diff --git a/models/migrations/v1_19/v234.go b/models/migrations/v1_19/v234.go
index c610a423dd..e00b1cc2b6 100644
--- a/models/migrations/v1_19/v234.go
+++ b/models/migrations/v1_19/v234.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_19/v235.go b/models/migrations/v1_19/v235.go
index 3715de3920..297d90f65a 100644
--- a/models/migrations/v1_19/v235.go
+++ b/models/migrations/v1_19/v235.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_19/v236.go b/models/migrations/v1_19/v236.go
index fa01a6ab80..c453f95e04 100644
--- a/models/migrations/v1_19/v236.go
+++ b/models/migrations/v1_19/v236.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_19/v237.go b/models/migrations/v1_19/v237.go
index b23c765aa5..cf30226ccd 100644
--- a/models/migrations/v1_19/v237.go
+++ b/models/migrations/v1_19/v237.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_19/v238.go b/models/migrations/v1_19/v238.go
index 7c912a8341..b257315319 100644
--- a/models/migrations/v1_19/v238.go
+++ b/models/migrations/v1_19/v238.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_19/v239.go b/models/migrations/v1_19/v239.go
index 10076f2401..8f4a65be95 100644
--- a/models/migrations/v1_19/v239.go
+++ b/models/migrations/v1_19/v239.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_19/v240.go b/models/migrations/v1_19/v240.go
index 4ca5becede..c49ce2f49a 100644
--- a/models/migrations/v1_19/v240.go
+++ b/models/migrations/v1_19/v240.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"forgejo.org/models/db"
diff --git a/models/migrations/v1_19/v241.go b/models/migrations/v1_19/v241.go
index a617d6fd2f..e35801a057 100644
--- a/models/migrations/v1_19/v241.go
+++ b/models/migrations/v1_19/v241.go
@@ -1,7 +1,7 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_19/v242.go b/models/migrations/v1_19/v242.go
index bbf227ef77..87ca9cf214 100644
--- a/models/migrations/v1_19/v242.go
+++ b/models/migrations/v1_19/v242.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"forgejo.org/modules/setting"
diff --git a/models/migrations/v1_19/v243.go b/models/migrations/v1_19/v243.go
index 55bbfafb2f..9c3f372594 100644
--- a/models/migrations/v1_19/v243.go
+++ b/models/migrations/v1_19/v243.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_19 //nolint
+package v1_19
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_20/main_test.go b/models/migrations/v1_20/main_test.go
index f870dca429..ee5eec5ef6 100644
--- a/models/migrations/v1_20/main_test.go
+++ b/models/migrations/v1_20/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"testing"
diff --git a/models/migrations/v1_20/v244.go b/models/migrations/v1_20/v244.go
index 977566ad7d..76cdccaca5 100644
--- a/models/migrations/v1_20/v244.go
+++ b/models/migrations/v1_20/v244.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_20/v245.go b/models/migrations/v1_20/v245.go
index 7e6585388b..5e034568c4 100644
--- a/models/migrations/v1_20/v245.go
+++ b/models/migrations/v1_20/v245.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"context"
diff --git a/models/migrations/v1_20/v246.go b/models/migrations/v1_20/v246.go
index e6340ef079..22bf723404 100644
--- a/models/migrations/v1_20/v246.go
+++ b/models/migrations/v1_20/v246.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_20/v247.go b/models/migrations/v1_20/v247.go
index 9ed810a623..056699d744 100644
--- a/models/migrations/v1_20/v247.go
+++ b/models/migrations/v1_20/v247.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"forgejo.org/modules/log"
diff --git a/models/migrations/v1_20/v248.go b/models/migrations/v1_20/v248.go
index 40555210e7..4f2091e4bc 100644
--- a/models/migrations/v1_20/v248.go
+++ b/models/migrations/v1_20/v248.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import "xorm.io/xorm"
diff --git a/models/migrations/v1_20/v249.go b/models/migrations/v1_20/v249.go
index d2b096bf58..0aebb2a343 100644
--- a/models/migrations/v1_20/v249.go
+++ b/models/migrations/v1_20/v249.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_20/v250.go b/models/migrations/v1_20/v250.go
index cfcde2fc9b..e12223691f 100644
--- a/models/migrations/v1_20/v250.go
+++ b/models/migrations/v1_20/v250.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"strings"
diff --git a/models/migrations/v1_20/v251.go b/models/migrations/v1_20/v251.go
index c8665ba7eb..7d2d259df6 100644
--- a/models/migrations/v1_20/v251.go
+++ b/models/migrations/v1_20/v251.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"forgejo.org/modules/log"
diff --git a/models/migrations/v1_20/v252.go b/models/migrations/v1_20/v252.go
index bb85c78309..435cce7ebe 100644
--- a/models/migrations/v1_20/v252.go
+++ b/models/migrations/v1_20/v252.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"forgejo.org/modules/log"
diff --git a/models/migrations/v1_20/v253.go b/models/migrations/v1_20/v253.go
index 5f4057e9d9..73354fd485 100644
--- a/models/migrations/v1_20/v253.go
+++ b/models/migrations/v1_20/v253.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"forgejo.org/modules/log"
diff --git a/models/migrations/v1_20/v254.go b/models/migrations/v1_20/v254.go
index 1e26979a5b..9cdbfb3916 100644
--- a/models/migrations/v1_20/v254.go
+++ b/models/migrations/v1_20/v254.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_20/v255.go b/models/migrations/v1_20/v255.go
index 49b0ecf220..baa3c4b6d8 100644
--- a/models/migrations/v1_20/v255.go
+++ b/models/migrations/v1_20/v255.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_20/v256.go b/models/migrations/v1_20/v256.go
index 822153b93e..7b84c1e154 100644
--- a/models/migrations/v1_20/v256.go
+++ b/models/migrations/v1_20/v256.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_20/v257.go b/models/migrations/v1_20/v257.go
index 70f229d73f..8045909dba 100644
--- a/models/migrations/v1_20/v257.go
+++ b/models/migrations/v1_20/v257.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_20/v258.go b/models/migrations/v1_20/v258.go
index 47174ce805..1d3faffdae 100644
--- a/models/migrations/v1_20/v258.go
+++ b/models/migrations/v1_20/v258.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_20/v259.go b/models/migrations/v1_20/v259.go
index f10b94fa9c..9b2b68263e 100644
--- a/models/migrations/v1_20/v259.go
+++ b/models/migrations/v1_20/v259.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"fmt"
diff --git a/models/migrations/v1_20/v259_test.go b/models/migrations/v1_20/v259_test.go
index 32e4aa3050..b41b6c7995 100644
--- a/models/migrations/v1_20/v259_test.go
+++ b/models/migrations/v1_20/v259_test.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_20 //nolint
+package v1_20
import (
"sort"
diff --git a/models/migrations/v1_21/main_test.go b/models/migrations/v1_21/main_test.go
index 7104887afb..3f10a39a94 100644
--- a/models/migrations/v1_21/main_test.go
+++ b/models/migrations/v1_21/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"testing"
diff --git a/models/migrations/v1_21/v260.go b/models/migrations/v1_21/v260.go
index 245f3011ab..b73b53bd61 100644
--- a/models/migrations/v1_21/v260.go
+++ b/models/migrations/v1_21/v260.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_21/v261.go b/models/migrations/v1_21/v261.go
index 743bef152d..83a4927704 100644
--- a/models/migrations/v1_21/v261.go
+++ b/models/migrations/v1_21/v261.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_21/v262.go b/models/migrations/v1_21/v262.go
index 23e900572a..6e88e29b9d 100644
--- a/models/migrations/v1_21/v262.go
+++ b/models/migrations/v1_21/v262.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_21/v263.go b/models/migrations/v1_21/v263.go
index 2c7cbadf0d..55c418bde0 100644
--- a/models/migrations/v1_21/v263.go
+++ b/models/migrations/v1_21/v263.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"fmt"
diff --git a/models/migrations/v1_21/v264.go b/models/migrations/v1_21/v264.go
index 5615600072..acd2c9bb48 100644
--- a/models/migrations/v1_21/v264.go
+++ b/models/migrations/v1_21/v264.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"context"
diff --git a/models/migrations/v1_21/v265.go b/models/migrations/v1_21/v265.go
index 800eb95f72..b6892acc27 100644
--- a/models/migrations/v1_21/v265.go
+++ b/models/migrations/v1_21/v265.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_21/v266.go b/models/migrations/v1_21/v266.go
index 79a5f5e14c..440549e868 100644
--- a/models/migrations/v1_21/v266.go
+++ b/models/migrations/v1_21/v266.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_21/v267.go b/models/migrations/v1_21/v267.go
index f94696a22b..13992d8776 100644
--- a/models/migrations/v1_21/v267.go
+++ b/models/migrations/v1_21/v267.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_21/v268.go b/models/migrations/v1_21/v268.go
index 332793ff07..b677d2383e 100644
--- a/models/migrations/v1_21/v268.go
+++ b/models/migrations/v1_21/v268.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_21/v269.go b/models/migrations/v1_21/v269.go
index 475ec02380..042040927d 100644
--- a/models/migrations/v1_21/v269.go
+++ b/models/migrations/v1_21/v269.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_21/v270.go b/models/migrations/v1_21/v270.go
index b9cc84d3ac..ab7c5660ba 100644
--- a/models/migrations/v1_21/v270.go
+++ b/models/migrations/v1_21/v270.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_21/v271.go b/models/migrations/v1_21/v271.go
index f45c113c1f..e3ce2d4b74 100644
--- a/models/migrations/v1_21/v271.go
+++ b/models/migrations/v1_21/v271.go
@@ -1,7 +1,8 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
+
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_21/v272.go b/models/migrations/v1_21/v272.go
index a729c49f1b..14c1e0c4b0 100644
--- a/models/migrations/v1_21/v272.go
+++ b/models/migrations/v1_21/v272.go
@@ -1,7 +1,8 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
+
import (
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_21/v273.go b/models/migrations/v1_21/v273.go
index 1ec6ade566..d6ec80d3d5 100644
--- a/models/migrations/v1_21/v273.go
+++ b/models/migrations/v1_21/v273.go
@@ -1,7 +1,8 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
+
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_21/v274.go b/models/migrations/v1_21/v274.go
index b74e5fed51..a1211d1fdd 100644
--- a/models/migrations/v1_21/v274.go
+++ b/models/migrations/v1_21/v274.go
@@ -1,7 +1,8 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
+
import (
"time"
diff --git a/models/migrations/v1_21/v275.go b/models/migrations/v1_21/v275.go
index 78804a59d6..2bfe5c72fa 100644
--- a/models/migrations/v1_21/v275.go
+++ b/models/migrations/v1_21/v275.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_21/v276.go b/models/migrations/v1_21/v276.go
index 0830c3bd92..3b0bc23da7 100644
--- a/models/migrations/v1_21/v276.go
+++ b/models/migrations/v1_21/v276.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
repo_model "forgejo.org/models/repo"
diff --git a/models/migrations/v1_21/v277.go b/models/migrations/v1_21/v277.go
index 12529160b7..0c102eddde 100644
--- a/models/migrations/v1_21/v277.go
+++ b/models/migrations/v1_21/v277.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_21/v278.go b/models/migrations/v1_21/v278.go
index d6a462d1e7..846f228678 100644
--- a/models/migrations/v1_21/v278.go
+++ b/models/migrations/v1_21/v278.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_21/v279.go b/models/migrations/v1_21/v279.go
index 2abd1bbe84..beb39effe1 100644
--- a/models/migrations/v1_21/v279.go
+++ b/models/migrations/v1_21/v279.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_21 //nolint
+package v1_21
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_22/main_test.go b/models/migrations/v1_22/main_test.go
index dc991b78fe..7b05993e09 100644
--- a/models/migrations/v1_22/main_test.go
+++ b/models/migrations/v1_22/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"testing"
diff --git a/models/migrations/v1_22/v280.go b/models/migrations/v1_22/v280.go
index a8ee4a3bf7..2271cb6089 100644
--- a/models/migrations/v1_22/v280.go
+++ b/models/migrations/v1_22/v280.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_22/v281.go b/models/migrations/v1_22/v281.go
index 5271c786be..2eeca9be82 100644
--- a/models/migrations/v1_22/v281.go
+++ b/models/migrations/v1_22/v281.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_22/v282.go b/models/migrations/v1_22/v282.go
index baad9e0916..eed64c30f7 100644
--- a/models/migrations/v1_22/v282.go
+++ b/models/migrations/v1_22/v282.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_22/v283.go b/models/migrations/v1_22/v283.go
index 86946d1c39..33a2513069 100644
--- a/models/migrations/v1_22/v283.go
+++ b/models/migrations/v1_22/v283.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_22/v283_test.go b/models/migrations/v1_22/v283_test.go
index d8e147a131..652d96ac16 100644
--- a/models/migrations/v1_22/v283_test.go
+++ b/models/migrations/v1_22/v283_test.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"testing"
diff --git a/models/migrations/v1_22/v284.go b/models/migrations/v1_22/v284.go
index 2b95078980..31b38f6aed 100644
--- a/models/migrations/v1_22/v284.go
+++ b/models/migrations/v1_22/v284.go
@@ -1,7 +1,8 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
+
import (
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_22/v285.go b/models/migrations/v1_22/v285.go
index a55cc17c04..fed89f670e 100644
--- a/models/migrations/v1_22/v285.go
+++ b/models/migrations/v1_22/v285.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"time"
diff --git a/models/migrations/v1_22/v286.go b/models/migrations/v1_22/v286.go
index d0489e7aeb..05247bb436 100644
--- a/models/migrations/v1_22/v286.go
+++ b/models/migrations/v1_22/v286.go
@@ -1,6 +1,6 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"fmt"
diff --git a/models/migrations/v1_22/v286_test.go b/models/migrations/v1_22/v286_test.go
index c63deef495..5bb3334df2 100644
--- a/models/migrations/v1_22/v286_test.go
+++ b/models/migrations/v1_22/v286_test.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"testing"
diff --git a/models/migrations/v1_22/v287.go b/models/migrations/v1_22/v287.go
index c8b1593286..5fd901f9de 100644
--- a/models/migrations/v1_22/v287.go
+++ b/models/migrations/v1_22/v287.go
@@ -1,7 +1,7 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_22/v288.go b/models/migrations/v1_22/v288.go
index 44e4991851..78be3b6ef2 100644
--- a/models/migrations/v1_22/v288.go
+++ b/models/migrations/v1_22/v288.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_22/v289.go b/models/migrations/v1_22/v289.go
index b9941aadd9..78689a4ffa 100644
--- a/models/migrations/v1_22/v289.go
+++ b/models/migrations/v1_22/v289.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import "xorm.io/xorm"
diff --git a/models/migrations/v1_22/v290.go b/models/migrations/v1_22/v290.go
index 594e417644..ebafab6567 100644
--- a/models/migrations/v1_22/v290.go
+++ b/models/migrations/v1_22/v290.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_22/v290_test.go b/models/migrations/v1_22/v290_test.go
index 569d77bc16..a1907cf4d6 100644
--- a/models/migrations/v1_22/v290_test.go
+++ b/models/migrations/v1_22/v290_test.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"strconv"
diff --git a/models/migrations/v1_22/v291.go b/models/migrations/v1_22/v291.go
index 74726fae96..823a644a95 100644
--- a/models/migrations/v1_22/v291.go
+++ b/models/migrations/v1_22/v291.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import "xorm.io/xorm"
diff --git a/models/migrations/v1_22/v292.go b/models/migrations/v1_22/v292.go
index beca556aee..440f48ce80 100644
--- a/models/migrations/v1_22/v292.go
+++ b/models/migrations/v1_22/v292.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
// NOTE: noop the original migration has bug which some projects will be skip, so
// these projects will have no default board.
diff --git a/models/migrations/v1_22/v293.go b/models/migrations/v1_22/v293.go
index 9f38c3db56..e9c9746b26 100644
--- a/models/migrations/v1_22/v293.go
+++ b/models/migrations/v1_22/v293.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"forgejo.org/modules/setting"
diff --git a/models/migrations/v1_22/v293_test.go b/models/migrations/v1_22/v293_test.go
index 444146737d..6b1931b761 100644
--- a/models/migrations/v1_22/v293_test.go
+++ b/models/migrations/v1_22/v293_test.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"testing"
diff --git a/models/migrations/v1_22/v294.go b/models/migrations/v1_22/v294.go
index 314b4519f1..6c52372306 100644
--- a/models/migrations/v1_22/v294.go
+++ b/models/migrations/v1_22/v294.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_22/v294_test.go b/models/migrations/v1_22/v294_test.go
index ef7b67ca5b..e87a4bc85f 100644
--- a/models/migrations/v1_22/v294_test.go
+++ b/models/migrations/v1_22/v294_test.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import (
"slices"
@@ -45,7 +45,8 @@ func Test_AddUniqueIndexForProjectIssue(t *testing.T) {
for _, index := range tables[0].Indexes {
if index.Type == schemas.UniqueType {
found = true
- slices.Equal(index.Cols, []string{"project_id", "issue_id"})
+ slices.Sort(index.Cols)
+ assert.Equal(t, []string{"issue_id", "project_id"}, index.Cols)
break
}
}
diff --git a/models/migrations/v1_22/v295.go b/models/migrations/v1_22/v295.go
index 17bdadb4ad..319b1a399b 100644
--- a/models/migrations/v1_22/v295.go
+++ b/models/migrations/v1_22/v295.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import "xorm.io/xorm"
diff --git a/models/migrations/v1_22/v296.go b/models/migrations/v1_22/v296.go
index 1ecacab95f..75350f9f65 100644
--- a/models/migrations/v1_22/v296.go
+++ b/models/migrations/v1_22/v296.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import "xorm.io/xorm"
diff --git a/models/migrations/v1_22/v298.go b/models/migrations/v1_22/v298.go
index b9f3b95ade..7700173a00 100644
--- a/models/migrations/v1_22/v298.go
+++ b/models/migrations/v1_22/v298.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_22 //nolint
+package v1_22
import "xorm.io/xorm"
diff --git a/models/migrations/v1_23/main_test.go b/models/migrations/v1_23/main_test.go
index 0fd90a4a67..5fb4fec999 100644
--- a/models/migrations/v1_23/main_test.go
+++ b/models/migrations/v1_23/main_test.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_23 //nolint
+package v1_23
import (
"testing"
diff --git a/models/migrations/v1_23/v299.go b/models/migrations/v1_23/v299.go
index f6db960c3b..73ce19c875 100644
--- a/models/migrations/v1_23/v299.go
+++ b/models/migrations/v1_23/v299.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_23 //nolint
+package v1_23
import "xorm.io/xorm"
diff --git a/models/migrations/v1_23/v300.go b/models/migrations/v1_23/v300.go
index f1f1cccdbf..404d8dbea8 100644
--- a/models/migrations/v1_23/v300.go
+++ b/models/migrations/v1_23/v300.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_23 //nolint
+package v1_23
import "xorm.io/xorm"
diff --git a/models/migrations/v1_23/v301.go b/models/migrations/v1_23/v301.go
index b7797f6c6b..f2a4d8c559 100644
--- a/models/migrations/v1_23/v301.go
+++ b/models/migrations/v1_23/v301.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_23 //nolint
+package v1_23
import "xorm.io/xorm"
diff --git a/models/migrations/v1_23/v302.go b/models/migrations/v1_23/v302.go
index c8ed786d63..1b056993bd 100644
--- a/models/migrations/v1_23/v302.go
+++ b/models/migrations/v1_23/v302.go
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_23 //nolint
+package v1_23
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_23/v303.go b/models/migrations/v1_23/v303.go
index fae0131bdd..03197d2857 100644
--- a/models/migrations/v1_23/v303.go
+++ b/models/migrations/v1_23/v303.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors.
// SPDX-License-Identifier: GPL-3.0-or-later
-package v1_23 //nolint
+package v1_23
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_23/v303_test.go b/models/migrations/v1_23/v303_test.go
index f105d11830..f2c764bae3 100644
--- a/models/migrations/v1_23/v303_test.go
+++ b/models/migrations/v1_23/v303_test.go
@@ -1,7 +1,7 @@
// Copyright 2025 The Forgejo Authors.
// SPDX-License-Identifier: GPL-3.0-or-later
-package v1_23 //nolint
+package v1_23
import (
"testing"
diff --git a/models/migrations/v1_6/v70.go b/models/migrations/v1_6/v70.go
index ec6bd09bb5..eb669f57b6 100644
--- a/models/migrations/v1_6/v70.go
+++ b/models/migrations/v1_6/v70.go
@@ -1,7 +1,7 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_6 //nolint
+package v1_6
import (
"fmt"
diff --git a/models/migrations/v1_6/v71.go b/models/migrations/v1_6/v71.go
index 3706ad4406..42fe8cd1ba 100644
--- a/models/migrations/v1_6/v71.go
+++ b/models/migrations/v1_6/v71.go
@@ -1,7 +1,7 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_6 //nolint
+package v1_6
import (
"fmt"
diff --git a/models/migrations/v1_6/v72.go b/models/migrations/v1_6/v72.go
index 4df2a0f6e9..7cd2331376 100644
--- a/models/migrations/v1_6/v72.go
+++ b/models/migrations/v1_6/v72.go
@@ -1,7 +1,7 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_6 //nolint
+package v1_6
import (
"fmt"
diff --git a/models/migrations/v1_7/v73.go b/models/migrations/v1_7/v73.go
index b5a748aae3..e0b7a28537 100644
--- a/models/migrations/v1_7/v73.go
+++ b/models/migrations/v1_7/v73.go
@@ -1,7 +1,7 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_7 //nolint
+package v1_7
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_7/v74.go b/models/migrations/v1_7/v74.go
index f0567e3c9b..376be37a24 100644
--- a/models/migrations/v1_7/v74.go
+++ b/models/migrations/v1_7/v74.go
@@ -1,7 +1,7 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_7 //nolint
+package v1_7
import "xorm.io/xorm"
diff --git a/models/migrations/v1_7/v75.go b/models/migrations/v1_7/v75.go
index fa7430970c..ef11575466 100644
--- a/models/migrations/v1_7/v75.go
+++ b/models/migrations/v1_7/v75.go
@@ -1,7 +1,7 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_7 //nolint
+package v1_7
import (
"xorm.io/builder"
diff --git a/models/migrations/v1_8/v76.go b/models/migrations/v1_8/v76.go
index 61ad006a47..8d47280b41 100644
--- a/models/migrations/v1_8/v76.go
+++ b/models/migrations/v1_8/v76.go
@@ -1,7 +1,7 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_8 //nolint
+package v1_8
import (
"fmt"
diff --git a/models/migrations/v1_8/v77.go b/models/migrations/v1_8/v77.go
index 8b19993924..4fe5ebe635 100644
--- a/models/migrations/v1_8/v77.go
+++ b/models/migrations/v1_8/v77.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_8 //nolint
+package v1_8
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_8/v78.go b/models/migrations/v1_8/v78.go
index 8102b19335..840fc20d96 100644
--- a/models/migrations/v1_8/v78.go
+++ b/models/migrations/v1_8/v78.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_8 //nolint
+package v1_8
import (
"forgejo.org/models/migrations/base"
diff --git a/models/migrations/v1_8/v79.go b/models/migrations/v1_8/v79.go
index f7d2d68f96..c8e0db531f 100644
--- a/models/migrations/v1_8/v79.go
+++ b/models/migrations/v1_8/v79.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_8 //nolint
+package v1_8
import (
"forgejo.org/modules/setting"
diff --git a/models/migrations/v1_8/v80.go b/models/migrations/v1_8/v80.go
index cebbbead28..6f9df47a93 100644
--- a/models/migrations/v1_8/v80.go
+++ b/models/migrations/v1_8/v80.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_8 //nolint
+package v1_8
import "xorm.io/xorm"
diff --git a/models/migrations/v1_8/v81.go b/models/migrations/v1_8/v81.go
index 734fc24641..8152a47ad7 100644
--- a/models/migrations/v1_8/v81.go
+++ b/models/migrations/v1_8/v81.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_8 //nolint
+package v1_8
import (
"fmt"
diff --git a/models/migrations/v1_9/v82.go b/models/migrations/v1_9/v82.go
index 78a90bdde9..235c73c504 100644
--- a/models/migrations/v1_9/v82.go
+++ b/models/migrations/v1_9/v82.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_9 //nolint
+package v1_9
import (
"fmt"
diff --git a/models/migrations/v1_9/v83.go b/models/migrations/v1_9/v83.go
index fa24a92d28..9640564a44 100644
--- a/models/migrations/v1_9/v83.go
+++ b/models/migrations/v1_9/v83.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_9 //nolint
+package v1_9
import (
"forgejo.org/modules/timeutil"
diff --git a/models/migrations/v1_9/v84.go b/models/migrations/v1_9/v84.go
index c7155fe9cf..423915ae57 100644
--- a/models/migrations/v1_9/v84.go
+++ b/models/migrations/v1_9/v84.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_9 //nolint
+package v1_9
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_9/v85.go b/models/migrations/v1_9/v85.go
index d8e9d91840..9d5adc82dd 100644
--- a/models/migrations/v1_9/v85.go
+++ b/models/migrations/v1_9/v85.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_9 //nolint
+package v1_9
import (
"fmt"
diff --git a/models/migrations/v1_9/v86.go b/models/migrations/v1_9/v86.go
index cf2725d158..9464ff0cf6 100644
--- a/models/migrations/v1_9/v86.go
+++ b/models/migrations/v1_9/v86.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_9 //nolint
+package v1_9
import (
"xorm.io/xorm"
diff --git a/models/migrations/v1_9/v87.go b/models/migrations/v1_9/v87.go
index fa01b6e5e3..81a4ebf80d 100644
--- a/models/migrations/v1_9/v87.go
+++ b/models/migrations/v1_9/v87.go
@@ -1,7 +1,7 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package v1_9 //nolint
+package v1_9
import (
"xorm.io/xorm"
diff --git a/models/packages/package.go b/models/packages/package.go
index bdd1c74cad..c06dcf5eb3 100644
--- a/models/packages/package.go
+++ b/models/packages/package.go
@@ -125,7 +125,7 @@ func (pt Type) Name() string {
case TypeRpm:
return "RPM"
case TypeAlt:
- return "Alt"
+ return "ALT"
case TypeRubyGems:
return "RubyGems"
case TypeSwift:
diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go
index c11ad70627..e50f79e945 100644
--- a/models/repo/repo_unit.go
+++ b/models/repo/repo_unit.go
@@ -41,27 +41,30 @@ func (err ErrUnitTypeNotExist) Unwrap() error {
}
// RepoUnitAccessMode specifies the users access mode to a repo unit
+// Only UnitAccessModeWrite is used by the wiki, to mark it as instance-writable
type UnitAccessMode int
const (
// UnitAccessModeUnset - no unit mode set
UnitAccessModeUnset UnitAccessMode = iota // 0
+
// UnitAccessModeNone no access
- UnitAccessModeNone // 1
+ // UnitAccessModeNone UnitAccessMode = 1
// UnitAccessModeRead read access
- UnitAccessModeRead // 2
+ // UnitAccessModeRead UnitAccessMode = 2
+
// UnitAccessModeWrite write access
- UnitAccessModeWrite // 3
+ UnitAccessModeWrite UnitAccessMode = 3
)
func (mode UnitAccessMode) ToAccessMode(modeIfUnset perm.AccessMode) perm.AccessMode {
switch mode {
case UnitAccessModeUnset:
return modeIfUnset
- case UnitAccessModeNone:
- return perm.AccessModeNone
- case UnitAccessModeRead:
- return perm.AccessModeRead
+ // case UnitAccessModeNone:
+ // return perm.AccessModeNone
+ // case UnitAccessModeRead:
+ // return perm.AccessModeRead
case UnitAccessModeWrite:
return perm.AccessModeWrite
default:
diff --git a/models/repo/repo_unit_test.go b/models/repo/repo_unit_test.go
index a1964519bd..3d6d408fcb 100644
--- a/models/repo/repo_unit_test.go
+++ b/models/repo/repo_unit_test.go
@@ -34,8 +34,8 @@ func TestActionsConfig(t *testing.T) {
}
func TestRepoUnitAccessMode(t *testing.T) {
- assert.Equal(t, perm.AccessModeNone, UnitAccessModeNone.ToAccessMode(perm.AccessModeAdmin))
- assert.Equal(t, perm.AccessModeRead, UnitAccessModeRead.ToAccessMode(perm.AccessModeAdmin))
+ // assert.Equal(t, perm.AccessModeNone, UnitAccessModeNone.ToAccessMode(perm.AccessModeAdmin))
+ // assert.Equal(t, perm.AccessModeRead, UnitAccessModeRead.ToAccessMode(perm.AccessModeAdmin))
assert.Equal(t, perm.AccessModeWrite, UnitAccessModeWrite.ToAccessMode(perm.AccessModeAdmin))
assert.Equal(t, perm.AccessModeRead, UnitAccessModeUnset.ToAccessMode(perm.AccessModeRead))
}
diff --git a/models/unittest/fixture_loader.go b/models/unittest/fixture_loader.go
index 67ef1b28df..dda5c48d35 100644
--- a/models/unittest/fixture_loader.go
+++ b/models/unittest/fixture_loader.go
@@ -12,6 +12,8 @@ import (
"path/filepath"
"strings"
+ "forgejo.org/modules/container"
+
"gopkg.in/yaml.v3"
)
@@ -32,13 +34,15 @@ type loader struct {
fixtureFiles []*fixtureFile
}
-func newFixtureLoader(db *sql.DB, dialect string, fixturePaths []string) (*loader, error) {
+func newFixtureLoader(db *sql.DB, dialect string, fixturePaths []string, allTableNames container.Set[string]) (*loader, error) {
l := &loader{
db: db,
dialect: dialect,
fixtureFiles: []*fixtureFile{},
}
+ tablesWithoutFixture := allTableNames
+
// Load fixtures
for _, fixturePath := range fixturePaths {
stat, err := os.Stat(fixturePath)
@@ -60,6 +64,7 @@ func newFixtureLoader(db *sql.DB, dialect string, fixturePaths []string) (*loade
return nil, err
}
l.fixtureFiles = append(l.fixtureFiles, fixtureFile)
+ tablesWithoutFixture.Remove(fixtureFile.name)
}
}
} else {
@@ -71,6 +76,14 @@ func newFixtureLoader(db *sql.DB, dialect string, fixturePaths []string) (*loade
}
}
+ // Even though these tables have no fixtures, they can still be used and ensure
+ // they are cleaned.
+ for table := range tablesWithoutFixture.Seq() {
+ l.fixtureFiles = append(l.fixtureFiles, &fixtureFile{
+ name: table,
+ })
+ }
+
return l, nil
}
@@ -178,13 +191,13 @@ func (l *loader) Load() error {
}()
// Clean the table and re-insert the fixtures.
- tableDeleted := map[string]struct{}{}
+ tableDeleted := make(container.Set[string])
for _, fixture := range l.fixtureFiles {
- if _, ok := tableDeleted[fixture.name]; !ok {
+ if !tableDeleted.Contains(fixture.name) {
if _, err := tx.Exec(fmt.Sprintf("DELETE FROM %s", l.quoteKeyword(fixture.name))); err != nil {
return fmt.Errorf("cannot delete table %s: %w", fixture.name, err)
}
- tableDeleted[fixture.name] = struct{}{}
+ tableDeleted.Add(fixture.name)
}
for _, insertSQL := range fixture.insertSQLs {
diff --git a/models/unittest/fixtures.go b/models/unittest/fixtures.go
index 6dc5c8412d..829cc16466 100644
--- a/models/unittest/fixtures.go
+++ b/models/unittest/fixtures.go
@@ -7,10 +7,12 @@ package unittest
import (
"fmt"
"path/filepath"
+ "sync"
"time"
"forgejo.org/models/db"
"forgejo.org/modules/auth/password/hash"
+ "forgejo.org/modules/container"
"forgejo.org/modules/setting"
"xorm.io/xorm"
@@ -44,6 +46,8 @@ func OverrideFixtures(dir string) func() {
}
}
+var allTableNames = sync.OnceValue(db.GetTableNames)
+
// InitFixtures initialize test fixtures for a test database
func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
e, err := GetXORMEngine(engine...)
@@ -75,7 +79,12 @@ func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
panic("Unsupported RDBMS for test")
}
- fixturesLoader, err = newFixtureLoader(e.DB().DB, dialect, fixturePaths)
+ var allTables container.Set[string]
+ if !opts.SkipCleanRegistedModels {
+ allTables = allTableNames().Clone()
+ }
+
+ fixturesLoader, err = newFixtureLoader(e.DB().DB, dialect, fixturePaths, allTables)
if err != nil {
return err
}
diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go
index d34c9e9a0a..29ec82c55f 100644
--- a/models/unittest/testdb.go
+++ b/models/unittest/testdb.go
@@ -217,6 +217,10 @@ type FixturesOptions struct {
Files []string
Dirs []string
Base string
+ // By default all registered models are cleaned, even if they do not have
+ // fixture. Enabling this will skip that and only models with fixtures are
+ // considered.
+ SkipCleanRegistedModels bool
}
// CreateTestEngine creates a memory database and loads the fixture data from fixturesDir
diff --git a/models/user/activitypub.go b/models/user/activitypub.go
index 816fd8a098..aabf2336fc 100644
--- a/models/user/activitypub.go
+++ b/models/user/activitypub.go
@@ -19,7 +19,7 @@ func (u *User) APActorID() string {
return fmt.Sprintf("%sapi/v1/activitypub/user-id/%s", setting.AppURL, url.PathEscape(fmt.Sprintf("%d", u.ID)))
}
-// APActorKeyID returns the ID of the user's public key
-func (u *User) APActorKeyID() string {
+// KeyID returns the ID of the user's public key
+func (u *User) KeyID() string {
return u.APActorID() + "#main-key"
}
diff --git a/models/user/email_address_test.go b/models/user/email_address_test.go
index 1801f57a23..85f5b16c65 100644
--- a/models/user/email_address_test.go
+++ b/models/user/email_address_test.go
@@ -181,3 +181,20 @@ func TestDeletePrimaryEmailAddressOfUser(t *testing.T) {
assert.True(t, user_model.IsErrEmailAddressNotExist(err))
assert.Nil(t, email)
}
+
+func TestActivateUserEmail(t *testing.T) {
+ defer unittest.OverrideFixtures("models/fixtures/TestActivateUserEmail")()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ t.Run("Activate email", func(t *testing.T) {
+ require.NoError(t, user_model.ActivateUserEmail(t.Context(), 1001, "AnotherTestUserWithUpperCaseEmail@otto.splvs.net", true))
+
+ unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{UID: 1001}, "is_activated = true")
+ })
+
+ t.Run("Deactivate email", func(t *testing.T) {
+ require.NoError(t, user_model.ActivateUserEmail(t.Context(), 1001, "AnotherTestUserWithUpperCaseEmail@otto.splvs.net", false))
+
+ unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{UID: 1001}, "is_activated = false")
+ })
+}
diff --git a/models/user/user.go b/models/user/user.go
index eedd1db80e..b124572bb6 100644
--- a/models/user/user.go
+++ b/models/user/user.go
@@ -182,11 +182,11 @@ func (u *User) BeforeUpdate() {
u.MaxRepoCreation = -1
}
- // Organization does not need email
- u.Email = strings.ToLower(u.Email)
+ // Ensure AvatarEmail is set for non-organization users, because organization
+ // are not required to have a email set.
if !u.IsOrganization() {
if len(u.AvatarEmail) == 0 {
- u.AvatarEmail = u.Email
+ u.AvatarEmail = strings.ToLower(u.Email)
}
}
diff --git a/models/user/user_repository.go b/models/user/user_repository.go
index 3f24efb1fb..85f44f1598 100644
--- a/models/user/user_repository.go
+++ b/models/user/user_repository.go
@@ -57,14 +57,6 @@ func CreateFederatedUser(ctx context.Context, user *User, federatedUser *Federat
return committer.Commit()
}
-func (federatedUser *FederatedUser) UpdateFederatedUser(ctx context.Context) error {
- if _, err := validation.IsValid(federatedUser); err != nil {
- return err
- }
- _, err := db.GetEngine(ctx).ID(federatedUser.ID).Cols("inbox_path").Update(federatedUser)
- return err
-}
-
func FindFederatedUser(ctx context.Context, externalID string, federationHostID int64) (*User, *FederatedUser, error) {
federatedUser := new(FederatedUser)
user := new(User)
@@ -219,7 +211,6 @@ func RemoveFollower(ctx context.Context, followedUser *User, followingUser *Fede
return err
}
-// TODO: We should unify Activity-pub-following and classical following (see models/user/follow.go)
func IsFollowingAp(ctx context.Context, followedUser *User, followingUser *FederatedUser) (bool, error) {
if res, err := validation.IsValid(followedUser); !res {
return false, err
diff --git a/models/user/user_test.go b/models/user/user_test.go
index fd9d05653f..f9a3aa6075 100644
--- a/models/user/user_test.go
+++ b/models/user/user_test.go
@@ -150,7 +150,7 @@ func TestAPActorID_APActorID(t *testing.T) {
func TestKeyID(t *testing.T) {
user := user_model.User{ID: 1}
- url := user.APActorKeyID()
+ url := user.KeyID()
expected := "https://try.gitea.io/api/v1/activitypub/user-id/1#main-key"
assert.Equal(t, expected, url)
}
diff --git a/modules/activitypub/client.go b/modules/activitypub/client.go
index d015fb7bec..fb6fa8b543 100644
--- a/modules/activitypub/client.go
+++ b/modules/activitypub/client.go
@@ -89,6 +89,7 @@ func NewClientFactory() (c *ClientFactory, err error) {
type APClientFactory interface {
WithKeys(ctx context.Context, user *user_model.User, pubID string) (APClient, error)
+ WithKeysDirect(ctx context.Context, privateKey, pubID string) (APClient, error)
}
// Client struct
@@ -103,12 +104,8 @@ type Client struct {
}
// NewRequest function
-func (cf *ClientFactory) WithKeys(ctx context.Context, user *user_model.User, pubID string) (APClient, error) {
- priv, err := GetPrivateKey(ctx, user)
- if err != nil {
- return nil, err
- }
- privPem, _ := pem.Decode([]byte(priv))
+func (cf *ClientFactory) WithKeysDirect(ctx context.Context, privateKey, pubID string) (APClient, error) {
+ privPem, _ := pem.Decode([]byte(privateKey))
privParsed, err := x509.ParsePKCS1PrivateKey(privPem.Bytes)
if err != nil {
return nil, err
@@ -126,6 +123,14 @@ func (cf *ClientFactory) WithKeys(ctx context.Context, user *user_model.User, pu
return &c, nil
}
+func (cf *ClientFactory) WithKeys(ctx context.Context, user *user_model.User, pubID string) (APClient, error) {
+ priv, err := GetPrivateKey(ctx, user)
+ if err != nil {
+ return nil, err
+ }
+ return cf.WithKeysDirect(ctx, priv, pubID)
+}
+
// NewRequest function
func (c *Client) newRequest(method string, b []byte, to string) (req *http.Request, err error) {
buf := bytes.NewBuffer(b)
@@ -149,12 +154,14 @@ func (c *Client) Post(b []byte, to string) (resp *http.Response, err error) {
return nil, err
}
- signer, _, err := httpsig.NewSigner(c.algs, c.digestAlg, c.postHeaders, httpsig.Signature, httpsigExpirationTime)
- if err != nil {
- return nil, err
- }
- if err := signer.SignRequest(c.priv, c.pubID, req, b); err != nil {
- return nil, err
+ if c.pubID != "" {
+ signer, _, err := httpsig.NewSigner(c.algs, c.digestAlg, c.postHeaders, httpsig.Signature, httpsigExpirationTime)
+ if err != nil {
+ return nil, err
+ }
+ if err := signer.SignRequest(c.priv, c.pubID, req, b); err != nil {
+ return nil, err
+ }
}
resp, err = c.client.Do(req)
@@ -167,12 +174,15 @@ func (c *Client) Get(to string) (resp *http.Response, err error) {
if req, err = c.newRequest(http.MethodGet, nil, to); err != nil {
return nil, err
}
- signer, _, err := httpsig.NewSigner(c.algs, c.digestAlg, c.getHeaders, httpsig.Signature, httpsigExpirationTime)
- if err != nil {
- return nil, err
- }
- if err := signer.SignRequest(c.priv, c.pubID, req, nil); err != nil {
- return nil, err
+
+ if c.pubID != "" {
+ signer, _, err := httpsig.NewSigner(c.algs, c.digestAlg, c.getHeaders, httpsig.Signature, httpsigExpirationTime)
+ if err != nil {
+ return nil, err
+ }
+ if err := signer.SignRequest(c.priv, c.pubID, req, nil); err != nil {
+ return nil, err
+ }
}
resp, err = c.client.Do(req)
diff --git a/modules/container/set.go b/modules/container/set.go
index 70f837bc66..d3719dc552 100644
--- a/modules/container/set.go
+++ b/modules/container/set.go
@@ -74,3 +74,8 @@ func (s Set[T]) Values() []T {
func (s Set[T]) Seq() iter.Seq[T] {
return maps.Keys(s)
}
+
+// Clone returns a identical shallow copy of this set.
+func (s Set[T]) Clone() Set[T] {
+ return maps.Clone(s)
+}
diff --git a/modules/container/set_test.go b/modules/container/set_test.go
index af5e9126ab..44e4847f6b 100644
--- a/modules/container/set_test.go
+++ b/modules/container/set_test.go
@@ -47,4 +47,11 @@ func TestSet(t *testing.T) {
assert.False(t, s.IsSubset([]string{"key1"}))
assert.True(t, s.IsSubset([]string{}))
+
+ t.Run("Clone", func(t *testing.T) {
+ clonedSet := s.Clone()
+ clonedSet.Remove("key6")
+ assert.False(t, clonedSet.Contains("key6"))
+ assert.True(t, s.Contains("key6"))
+ })
}
diff --git a/modules/git/blob.go b/modules/git/blob.go
index 14ca2b1445..4eef5f0e2a 100644
--- a/modules/git/blob.go
+++ b/modules/git/blob.go
@@ -220,7 +220,7 @@ func (b *Blob) GuessContentType() (typesniffer.SniffedType, error) {
}
defer r.Close()
- return typesniffer.DetectContentTypeFromReader(r)
+ return typesniffer.DetectContentTypeFromReader(r, b.Name())
}
// GetBlob finds the blob object in the repository.
diff --git a/modules/git/pushoptions/pushoptions.go b/modules/git/pushoptions/pushoptions.go
index 9709a8be79..e96ba0a339 100644
--- a/modules/git/pushoptions/pushoptions.go
+++ b/modules/git/pushoptions/pushoptions.go
@@ -4,6 +4,7 @@
package pushoptions
import (
+ "encoding/base64"
"fmt"
"os"
"strconv"
@@ -109,5 +110,22 @@ func (o gitPushOptions) GetBool(key Key, def bool) bool {
func (o gitPushOptions) GetString(key Key) (string, bool) {
val, ok := o[string(key)]
- return val, ok
+ if !ok {
+ return "", false
+ }
+
+ // If the value is prefixed with `{base64}` then everything after that is very
+ // likely to be encoded via base64.
+ base64Value, found := strings.CutPrefix(val, "{base64}")
+ if !found {
+ return val, true
+ }
+
+ value, err := base64.StdEncoding.DecodeString(base64Value)
+ if err != nil {
+ // Not valid base64? Return the original value.
+ return val, true
+ }
+
+ return string(value), true
}
diff --git a/modules/git/pushoptions/pushoptions_test.go b/modules/git/pushoptions/pushoptions_test.go
index 1cb36d9d1e..d7c50649d0 100644
--- a/modules/git/pushoptions/pushoptions_test.go
+++ b/modules/git/pushoptions/pushoptions_test.go
@@ -4,6 +4,7 @@
package pushoptions
import (
+ "encoding/base64"
"fmt"
"testing"
@@ -92,6 +93,23 @@ func TestParse(t *testing.T) {
assert.False(t, options.Parse("unknown=value"))
assert.True(t, options.Empty())
})
+
+ t.Run("Base64 values", func(t *testing.T) {
+ options := New()
+
+ description := `I contain
+a
+line`
+ assert.True(t, options.Parse(fmt.Sprintf("%s={base64}%s", AgitDescription, base64.StdEncoding.EncodeToString([]byte(description)))))
+ val, ok := options.GetString(AgitDescription)
+ assert.True(t, ok)
+ assert.Equal(t, description, val)
+
+ assert.True(t, options.Parse(fmt.Sprintf("%s={base64}fooled you", AgitTitle)))
+ val, ok = options.GetString(AgitTitle)
+ assert.True(t, ok)
+ assert.Equal(t, "{base64}fooled you", val)
+ })
}
func TestReadEnv(t *testing.T) {
diff --git a/modules/git/repo_blame.go b/modules/git/repo_blame.go
index 139cdd7be9..d812354af5 100644
--- a/modules/git/repo_blame.go
+++ b/modules/git/repo_blame.go
@@ -4,20 +4,46 @@
package git
import (
+ "errors"
"fmt"
+ "regexp"
+)
+
+var (
+ ErrBlameFileDoesNotExist = errors.New("the blamed file does not exist")
+ ErrBlameFileNotEnoughLines = errors.New("the blamed file has not enough lines")
+
+ notEnoughLinesRe = regexp.MustCompile(`^fatal: file .+ has only \d+ lines?\n$`)
)
// LineBlame returns the latest commit at the given line
-func (repo *Repository) LineBlame(revision, path, file string, line uint) (*Commit, error) {
- res, _, err := NewCommand(repo.Ctx, "blame").
+func (repo *Repository) LineBlame(revision, file string, line uint64) (*Commit, error) {
+ res, _, gitErr := NewCommand(repo.Ctx, "blame").
AddOptionFormat("-L %d,%d", line, line).
AddOptionValues("-p", revision).
- AddDashesAndList(file).RunStdString(&RunOpts{Dir: path})
+ AddDashesAndList(file).RunStdString(&RunOpts{Dir: repo.Path})
+ if gitErr != nil {
+ stdErr := gitErr.Stderr()
+
+ if stdErr == fmt.Sprintf("fatal: no such path %s in %s\n", file, revision) {
+ return nil, ErrBlameFileDoesNotExist
+ }
+ if notEnoughLinesRe.MatchString(stdErr) {
+ return nil, ErrBlameFileNotEnoughLines
+ }
+
+ return nil, gitErr
+ }
+
+ objectFormat, err := repo.GetObjectFormat()
if err != nil {
return nil, err
}
- if len(res) < 40 {
- return nil, fmt.Errorf("invalid result of blame: %s", res)
+
+ objectIDLen := objectFormat.FullLength()
+ if len(res) < objectIDLen {
+ return nil, fmt.Errorf("output of blame is invalid, cannot contain commit ID: %s", res)
}
- return repo.GetCommit(res[:40])
+
+ return repo.GetCommit(res[:objectIDLen])
}
diff --git a/modules/git/repo_blame_test.go b/modules/git/repo_blame_test.go
new file mode 100644
index 0000000000..126b95386d
--- /dev/null
+++ b/modules/git/repo_blame_test.go
@@ -0,0 +1,52 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package git
+
+import (
+ "path/filepath"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestLineBlame(t *testing.T) {
+ t.Run("SHA1", func(t *testing.T) {
+ repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
+ require.NoError(t, err)
+ defer repo.Close()
+
+ commit, err := repo.LineBlame("HEAD", "foo/link_short", 1)
+ require.NoError(t, err)
+ assert.Equal(t, "37991dec2c8e592043f47155ce4808d4580f9123", commit.ID.String())
+
+ commit, err = repo.LineBlame("HEAD", "foo/link_short", 512)
+ require.ErrorIs(t, err, ErrBlameFileNotEnoughLines)
+ assert.Nil(t, commit)
+
+ commit, err = repo.LineBlame("HEAD", "non-existent/path", 512)
+ require.ErrorIs(t, err, ErrBlameFileDoesNotExist)
+ assert.Nil(t, commit)
+ })
+
+ t.Run("SHA256", func(t *testing.T) {
+ skipIfSHA256NotSupported(t)
+
+ repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare_sha256"))
+ require.NoError(t, err)
+ defer repo.Close()
+
+ commit, err := repo.LineBlame("HEAD", "foo/link_short", 1)
+ require.NoError(t, err)
+ assert.Equal(t, "6aae864a3d1d0d6a5be0cc64028c1e7021e2632b031fd8eb82afc5a283d1c3d1", commit.ID.String())
+
+ commit, err = repo.LineBlame("HEAD", "foo/link_short", 512)
+ require.ErrorIs(t, err, ErrBlameFileNotEnoughLines)
+ assert.Nil(t, commit)
+
+ commit, err = repo.LineBlame("HEAD", "non-existent/path", 512)
+ require.ErrorIs(t, err, ErrBlameFileDoesNotExist)
+ assert.Nil(t, commit)
+ })
+}
diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go
index 3a9aa3e4e6..1e38bf2946 100644
--- a/modules/git/repo_branch.go
+++ b/modules/git/repo_branch.go
@@ -19,15 +19,9 @@ import (
// BranchPrefix base dir of the branch information file store on git
const BranchPrefix = "refs/heads/"
-// IsReferenceExist returns true if given reference exists in the repository.
-func IsReferenceExist(ctx context.Context, repoPath, name string) bool {
- _, _, err := NewCommand(ctx, "show-ref", "--verify").AddDashesAndList(name).RunStdString(&RunOpts{Dir: repoPath})
- return err == nil
-}
-
// IsBranchExist returns true if given branch exists in the repository.
func IsBranchExist(ctx context.Context, repoPath, name string) bool {
- return IsReferenceExist(ctx, repoPath, BranchPrefix+name)
+ return NewCommand(ctx, "show-ref", "--verify", "--quiet").AddDashesAndList(BranchPrefix+name).Run(&RunOpts{Dir: repoPath}) == nil
}
// Branch represents a Git branch.
diff --git a/modules/git/repo_branch_test.go b/modules/git/repo_branch_test.go
index 1e0fea7cd4..e61ea6f5d7 100644
--- a/modules/git/repo_branch_test.go
+++ b/modules/git/repo_branch_test.go
@@ -1,4 +1,5 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
+// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package git
@@ -195,3 +196,17 @@ func TestRepository_IsReferenceExist(t *testing.T) {
})
}
}
+
+func TestIsBranchExist(t *testing.T) {
+ repo1Path := filepath.Join(testReposDir, "repo1_bare")
+
+ assert.True(t, IsBranchExist(t.Context(), repo1Path, "branch1"))
+ assert.True(t, IsBranchExist(t.Context(), repo1Path, "branch2"))
+ assert.True(t, IsBranchExist(t.Context(), repo1Path, "master"))
+
+ assert.False(t, IsBranchExist(t.Context(), repo1Path, "HEAD"))
+ assert.False(t, IsBranchExist(t.Context(), repo1Path, "153f451b9ee7fa1da317ab17a127e9fd9d384310"))
+ assert.False(t, IsBranchExist(t.Context(), repo1Path, "153f451b9ee7fa1da317ab17a127e9fd9d384310"))
+ assert.False(t, IsBranchExist(t.Context(), repo1Path, "signed-tag"))
+ assert.False(t, IsBranchExist(t.Context(), repo1Path, "test"))
+}
diff --git a/modules/httplib/serve.go b/modules/httplib/serve.go
index c5f0658d4e..d385ac21c9 100644
--- a/modules/httplib/serve.go
+++ b/modules/httplib/serve.go
@@ -99,7 +99,7 @@ func setServeHeadersByFile(r *http.Request, w http.ResponseWriter, filePath stri
Filename: path.Base(filePath),
}
- sniffedType := typesniffer.DetectContentType(mineBuf)
+ sniffedType := typesniffer.DetectContentType(mineBuf, opts.Filename)
// the "render" parameter came from year 2016: 638dd24c, it doesn't have clear meaning, so I think it could be removed later
isPlain := sniffedType.IsText() || r.FormValue("render") != ""
diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go
index c53b7a2e6d..4c8b5f2a86 100644
--- a/modules/indexer/code/bleve/bleve.go
+++ b/modules/indexer/code/bleve/bleve.go
@@ -177,7 +177,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
fileContents, err := io.ReadAll(io.LimitReader(batchReader, size))
if err != nil {
return err
- } else if !typesniffer.DetectContentType(fileContents).IsText() {
+ } else if !typesniffer.DetectContentType(fileContents, update.Filename).IsText() {
// FIXME: UTF-16 files will probably fail here
// Even if the file is not recognized as a "text file", we could still put its name into the indexers to make the filename become searchable, while leave the content to empty.
fileContents = nil
diff --git a/modules/indexer/code/elasticsearch/elasticsearch.go b/modules/indexer/code/elasticsearch/elasticsearch.go
index 3903d77fe0..9b11f56fb7 100644
--- a/modules/indexer/code/elasticsearch/elasticsearch.go
+++ b/modules/indexer/code/elasticsearch/elasticsearch.go
@@ -144,7 +144,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
fileContents, err := io.ReadAll(io.LimitReader(batchReader, size))
if err != nil {
return nil, err
- } else if !typesniffer.DetectContentType(fileContents).IsText() {
+ } else if !typesniffer.DetectContentType(fileContents, update.Filename).IsText() {
// FIXME: UTF-16 files will probably fail here
return nil, nil
}
diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go
index 8549ba8dfc..cb98f722c5 100644
--- a/modules/indexer/issues/bleve/bleve.go
+++ b/modules/indexer/issues/bleve/bleve.go
@@ -156,11 +156,12 @@ func (b *Indexer) Delete(_ context.Context, ids ...int64) error {
func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (*internal.SearchResult, error) {
var queries []query.Query
- if options.Keyword != "" {
- tokens, err := options.Tokens()
- if err != nil {
- return nil, err
- }
+ tokens, err := options.Tokens()
+ if err != nil {
+ return nil, err
+ }
+
+ if len(tokens) > 0 {
q := bleve.NewBooleanQuery()
for _, token := range tokens {
innerQ := bleve.NewDisjunctionQuery(
diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go
index d632a22b2a..311e92730e 100644
--- a/modules/indexer/issues/elasticsearch/elasticsearch.go
+++ b/modules/indexer/issues/elasticsearch/elasticsearch.go
@@ -149,12 +149,13 @@ func (b *Indexer) Delete(ctx context.Context, ids ...int64) error {
func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (*internal.SearchResult, error) {
query := elastic.NewBoolQuery()
- if options.Keyword != "" {
+ tokens, err := options.Tokens()
+ if err != nil {
+ return nil, err
+ }
+
+ if len(tokens) > 0 {
q := elastic.NewBoolQuery()
- tokens, err := options.Tokens()
- if err != nil {
- return nil, err
- }
for _, token := range tokens {
innerQ := elastic.NewMultiMatchQuery(token.Term, "content", "comments").FieldWithBoost("title", 2.0).TieBreaker(0.5)
if token.Fuzzy {
diff --git a/modules/indexer/issues/internal/qstring.go b/modules/indexer/issues/internal/qstring.go
index 6b60b4c5f6..348f7a564b 100644
--- a/modules/indexer/issues/internal/qstring.go
+++ b/modules/indexer/issues/internal/qstring.go
@@ -45,12 +45,9 @@ func (t *Tokenizer) next() (tk Token, err error) {
// skip all leading white space
for {
- if r, _, err = t.in.ReadRune(); err == nil && r == ' ' {
- //nolint:staticcheck,wastedassign // SA4006 the variable is used after the loop
- r, _, err = t.in.ReadRune()
- continue
+ if r, _, err = t.in.ReadRune(); err != nil || r != ' ' {
+ break
}
- break
}
if err != nil {
return tk, err
@@ -107,11 +104,17 @@ nextEnd:
// Tokenize the keyword
func (o *SearchOptions) Tokens() (tokens []Token, err error) {
+ if o.Keyword == "" {
+ return nil, nil
+ }
+
in := strings.NewReader(o.Keyword)
it := Tokenizer{in: in}
for token, err := it.next(); err == nil; token, err = it.next() {
- tokens = append(tokens, token)
+ if token.Term != "" {
+ tokens = append(tokens, token)
+ }
}
if err != nil && err != io.EOF {
return nil, err
diff --git a/modules/indexer/issues/internal/qstring_test.go b/modules/indexer/issues/internal/qstring_test.go
index 835491707c..eb4bdb306f 100644
--- a/modules/indexer/issues/internal/qstring_test.go
+++ b/modules/indexer/issues/internal/qstring_test.go
@@ -41,6 +41,36 @@ var testOpts = []testIssueQueryStringOpt{
},
},
},
+ {
+ Keyword: "Hello World",
+ Results: []Token{
+ {
+ Term: "Hello",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ {
+ Term: "World",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: " Hello World ",
+ Results: []Token{
+ {
+ Term: "Hello",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ {
+ Term: "World",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
{
Keyword: "+Hello +World",
Results: []Token{
@@ -156,6 +186,68 @@ var testOpts = []testIssueQueryStringOpt{
},
},
},
+ {
+ Keyword: "\\",
+ Results: nil,
+ },
+ {
+ Keyword: "\"",
+ Results: nil,
+ },
+ {
+ Keyword: "Hello \\",
+ Results: []Token{
+ {
+ Term: "Hello",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: "\"\"",
+ Results: nil,
+ },
+ {
+ Keyword: "\" World \"",
+ Results: []Token{
+ {
+ Term: " World ",
+ Fuzzy: false,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: "\"\" World \"\"",
+ Results: []Token{
+ {
+ Term: "World",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: "Best \"Hello World\" Ever",
+ Results: []Token{
+ {
+ Term: "Best",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ {
+ Term: "Hello World",
+ Fuzzy: false,
+ Kind: BoolOptShould,
+ },
+ {
+ Term: "Ever",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
}
func TestIssueQueryString(t *testing.T) {
diff --git a/modules/indexer/issues/internal/tests/tests.go b/modules/indexer/issues/internal/tests/tests.go
index b63957ff84..46014994a0 100644
--- a/modules/indexer/issues/internal/tests/tests.go
+++ b/modules/indexer/issues/internal/tests/tests.go
@@ -87,14 +87,44 @@ func TestIndexer(t *testing.T, indexer internal.Indexer) {
}
}
+func allResults(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
+ assert.Len(t, result.Hits, len(data))
+ assert.Equal(t, len(data), int(result.Total))
+}
+
var cases = []*testIndexerCase{
{
Name: "default",
SearchOptions: &internal.SearchOptions{},
- Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Len(t, result.Hits, len(data))
- assert.Equal(t, len(data), int(result.Total))
+ Expected: allResults,
+ },
+ {
+ Name: "empty keyword",
+ SearchOptions: &internal.SearchOptions{
+ Keyword: "",
},
+ Expected: allResults,
+ },
+ {
+ Name: "whitespace keyword",
+ SearchOptions: &internal.SearchOptions{
+ Keyword: " ",
+ },
+ Expected: allResults,
+ },
+ {
+ Name: "dangling slash in keyword",
+ SearchOptions: &internal.SearchOptions{
+ Keyword: "\\",
+ },
+ Expected: allResults,
+ },
+ {
+ Name: "dangling quote in keyword",
+ SearchOptions: &internal.SearchOptions{
+ Keyword: "\"",
+ },
+ Expected: allResults,
},
{
Name: "empty",
diff --git a/modules/log/event_writer.go b/modules/log/event_writer.go
index 4b77e488de..32b5b582c5 100644
--- a/modules/log/event_writer.go
+++ b/modules/log/event_writer.go
@@ -26,6 +26,7 @@ type WriterMode struct {
Flags Flags
Expression string
+ Exclusion string
StacktraceLevel Level
diff --git a/modules/log/event_writer_base.go b/modules/log/event_writer_base.go
index 9189ca4e90..4de2b953c7 100644
--- a/modules/log/event_writer_base.go
+++ b/modules/log/event_writer_base.go
@@ -68,6 +68,14 @@ func (b *EventWriterBaseImpl) Run(ctx context.Context) {
}
}
+ var exclusionRegexp *regexp.Regexp
+ if b.Mode.Exclusion != "" {
+ var err error
+ if exclusionRegexp, err = regexp.Compile(b.Mode.Exclusion); err != nil {
+ FallbackErrorf("unable to compile exclusion %q for writer %q: %v", b.Mode.Exclusion, b.Name, err)
+ }
+ }
+
handlePaused := func() {
if pause := b.GetPauseChan(); pause != nil {
select {
@@ -95,6 +103,13 @@ func (b *EventWriterBaseImpl) Run(ctx context.Context) {
continue
}
}
+ if exclusionRegexp != nil {
+ fileLineCaller := fmt.Sprintf("%s:%d:%s", event.Origin.Filename, event.Origin.Line, event.Origin.Caller)
+ matched := exclusionRegexp.MatchString(fileLineCaller) || exclusionRegexp.MatchString(event.Origin.MsgSimpleText)
+ if matched {
+ continue
+ }
+ }
var err error
switch msg := event.Msg.(type) {
diff --git a/modules/log/event_writer_buffer_test.go b/modules/log/event_writer_buffer_test.go
index ba9455ba69..d1e37c3673 100644
--- a/modules/log/event_writer_buffer_test.go
+++ b/modules/log/event_writer_buffer_test.go
@@ -31,3 +31,49 @@ func TestBufferLogger(t *testing.T) {
logger.Close()
assert.Contains(t, bufferWriter.Buffer.String(), expected)
}
+
+func TestBufferLoggerWithExclusion(t *testing.T) {
+ prefix := "ExclusionPrefix "
+ level := log.INFO
+ message := "something"
+
+ bufferWriter := log.NewEventWriterBuffer("test-buffer", log.WriterMode{
+ Level: level,
+ Prefix: prefix,
+ Exclusion: message,
+ })
+
+ logger := log.NewLoggerWithWriters(t.Context(), "test", bufferWriter)
+
+ logger.SendLogEvent(&log.Event{
+ Level: log.INFO,
+ MsgSimpleText: message,
+ })
+ logger.Close()
+ assert.NotContains(t, bufferWriter.Buffer.String(), message)
+}
+
+func TestBufferLoggerWithExpressionAndExclusion(t *testing.T) {
+ prefix := "BothPrefix "
+ level := log.INFO
+ expression := ".*foo.*"
+ exclusion := ".*bar.*"
+
+ bufferWriter := log.NewEventWriterBuffer("test-buffer", log.WriterMode{
+ Level: level,
+ Prefix: prefix,
+ Expression: expression,
+ Exclusion: exclusion,
+ })
+
+ logger := log.NewLoggerWithWriters(t.Context(), "test", bufferWriter)
+
+ logger.SendLogEvent(&log.Event{Level: log.INFO, MsgSimpleText: "foo expression"})
+ logger.SendLogEvent(&log.Event{Level: log.INFO, MsgSimpleText: "bar exclusion"})
+ logger.SendLogEvent(&log.Event{Level: log.INFO, MsgSimpleText: "foo bar both"})
+ logger.SendLogEvent(&log.Event{Level: log.INFO, MsgSimpleText: "none"})
+ logger.Close()
+
+ assert.Contains(t, bufferWriter.Buffer.String(), "foo expression")
+ assert.NotContains(t, bufferWriter.Buffer.String(), "bar")
+}
diff --git a/modules/log/logger_test.go b/modules/log/logger_test.go
index 6d6ceb69d7..99045b0f4f 100644
--- a/modules/log/logger_test.go
+++ b/modules/log/logger_test.go
@@ -143,3 +143,19 @@ func TestLoggerExpressionFilter(t *testing.T) {
assert.Equal(t, []string{"foo\n", "foo bar\n", "by filename\n"}, w1.GetLogs())
}
+
+func TestLoggerExclusionFilter(t *testing.T) {
+ logger := NewLoggerWithWriters(t.Context(), "test")
+
+ w1 := newDummyWriter("dummy-1", DEBUG, 0)
+ w1.Mode.Exclusion = "foo.*"
+ logger.AddWriters(w1)
+
+ logger.Info("foo")
+ logger.Info("bar")
+ logger.Info("foo bar")
+ logger.SendLogEvent(&Event{Level: INFO, Filename: "foo.go", MsgSimpleText: "by filename"})
+ logger.Close()
+
+ assert.Equal(t, []string{"bar\n"}, w1.GetLogs())
+}
diff --git a/modules/markup/markdown/goldmark.go b/modules/markup/markdown/goldmark.go
index d229afa8e3..67d81488fd 100644
--- a/modules/markup/markdown/goldmark.go
+++ b/modules/markup/markdown/goldmark.go
@@ -9,6 +9,7 @@ import (
"strings"
"forgejo.org/modules/markup"
+ markdownutil "forgejo.org/modules/markup/markdown/util"
"forgejo.org/modules/setting"
"github.com/yuin/goldmark/ast"
@@ -35,8 +36,8 @@ func (g *ASTTransformer) applyElementDir(n ast.Node) {
func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) {
firstChild := node.FirstChild()
tocMode := ""
- ctx := pc.Get(renderContextKey).(*markup.RenderContext)
- rc := pc.Get(renderConfigKey).(*RenderConfig)
+ ctx := pc.Get(markdownutil.RenderContextKey).(*markup.RenderContext)
+ rc := pc.Get(markdownutil.RenderConfigKey).(*RenderConfig)
tocList := make([]markup.Header, 0, 20)
if rc.yamlNode != nil {
diff --git a/modules/markup/markdown/markdown.go b/modules/markup/markdown/markdown.go
index e811d29994..2b19e0f1c9 100644
--- a/modules/markup/markdown/markdown.go
+++ b/modules/markup/markdown/markdown.go
@@ -16,6 +16,7 @@ import (
"forgejo.org/modules/markup/common"
"forgejo.org/modules/markup/markdown/callout"
"forgejo.org/modules/markup/markdown/math"
+ markdownutil "forgejo.org/modules/markup/markdown/util"
"forgejo.org/modules/setting"
giteautil "forgejo.org/modules/util"
@@ -34,11 +35,6 @@ var (
specMarkdownOnce sync.Once
)
-var (
- renderContextKey = parser.NewContextKey()
- renderConfigKey = parser.NewContextKey()
-)
-
type limitWriter struct {
w io.Writer
sum int64
@@ -64,7 +60,7 @@ func (l *limitWriter) Write(data []byte) (int, error) {
// newParserContext creates a parser.Context with the render context set
func newParserContext(ctx *markup.RenderContext) parser.Context {
pc := parser.NewContext(parser.WithIDs(newPrefixedIDs()))
- pc.Set(renderContextKey, ctx)
+ pc.Set(markdownutil.RenderContextKey, ctx)
return pc
}
@@ -192,7 +188,7 @@ func actualRender(ctx *markup.RenderContext, input io.Reader, output io.Writer)
}
rc.metaLength = metaLength
- pc.Set(renderConfigKey, rc)
+ pc.Set(markdownutil.RenderConfigKey, rc)
if err := converter.Convert(buf, lw, parser.WithContext(pc)); err != nil {
log.Error("Unable to render: %v", err)
diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go
index f7955115e0..c854861031 100644
--- a/modules/markup/markdown/markdown_test.go
+++ b/modules/markup/markdown/markdown_test.go
@@ -561,6 +561,14 @@ func TestMathBlock(t *testing.T) {
"test $$a$$",
`
test a
` + nl,
},
+ {
+ `\[
+[\triangle ABC] = \sqrt{s(s-a)(s-b)(s-c)}
+\]`,
+ `[
+[\triangle ABC] = \sqrt{s(s-a)(s-b)(s-c)}
+]
` + nl,
+ },
}
for _, test := range testcases {
@@ -568,6 +576,32 @@ func TestMathBlock(t *testing.T) {
require.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase)
}
+
+ t.Run("Wiki context", func(t *testing.T) {
+ testcases := []struct {
+ testcase string
+ expected string
+ }{
+ {
+ "$a$",
+ `a
` + nl,
+ },
+ {
+ `\[
+[\triangle ABC] = \sqrt{s(s-a)(s-b)(s-c)}
+\]`,
+ `
+[\triangle ABC] = \sqrt{s(s-a)(s-b)(s-c)}
+
` + nl,
+ },
+ }
+
+ for _, test := range testcases {
+ res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext, IsWiki: true}, test.testcase)
+ require.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
+ assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase)
+ }
+ })
}
func TestFootnote(t *testing.T) {
diff --git a/modules/markup/markdown/math/block_parser.go b/modules/markup/markdown/math/block_parser.go
index 527df84975..b0fe1d588a 100644
--- a/modules/markup/markdown/math/block_parser.go
+++ b/modules/markup/markdown/math/block_parser.go
@@ -6,6 +6,9 @@ package math
import (
"bytes"
+ "forgejo.org/modules/markup"
+ markdownutil "forgejo.org/modules/markup/markdown/util"
+
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/text"
@@ -61,6 +64,13 @@ func (b *blockParser) Open(parent ast.Node, reader text.Reader, pc parser.Contex
return node, parser.Close | parser.NoChildren
}
+ ctx := pc.Get(markdownutil.RenderContextKey).(*markup.RenderContext)
+ if ctx.IsWiki {
+ reader.Advance(segment.Len() - 1)
+ segment.Start += 2
+ node.Lines().Append(segment)
+ return node, parser.NoChildren
+ }
return nil, parser.NoChildren
}
diff --git a/modules/markup/markdown/util/text.go b/modules/markup/markdown/util/text.go
index 8a42e5835b..db6e432e79 100644
--- a/modules/markup/markdown/util/text.go
+++ b/modules/markup/markdown/util/text.go
@@ -7,6 +7,7 @@ import (
"bytes"
"github.com/yuin/goldmark/ast"
+ "github.com/yuin/goldmark/parser"
)
func textOfChildren(n ast.Node, src []byte, b *bytes.Buffer) {
@@ -24,3 +25,8 @@ func Text(n ast.Node, src []byte) []byte {
textOfChildren(n, src, &b)
return b.Bytes()
}
+
+var (
+ RenderContextKey = parser.NewContextKey()
+ RenderConfigKey = parser.NewContextKey()
+)
diff --git a/modules/packages/rpm/metadata.go b/modules/packages/rpm/metadata.go
index 4af9af620f..503b7b1a24 100644
--- a/modules/packages/rpm/metadata.go
+++ b/modules/packages/rpm/metadata.go
@@ -232,9 +232,10 @@ func getEntries(h *rpmutils.RpmHeader, namesTag, versionsTag, flagsTag int, repo
case "alt":
for i := range names {
e := &Entry{
+ Name: names[i],
AltFlags: uint32(flags[i]),
+ Version: versions[i],
}
- e.Version = versions[i]
entries = append(entries, e)
}
}
diff --git a/modules/setting/incoming_email.go b/modules/setting/incoming_email.go
index e592220de6..a890a4a328 100644
--- a/modules/setting/incoming_email.go
+++ b/modules/setting/incoming_email.go
@@ -44,9 +44,14 @@ func loadIncomingEmailFrom(rootCfg ConfigProvider) {
if sec.HasKey("USER") && !sec.HasKey("USERNAME") {
IncomingEmail.Username = sec.Key("USER").String()
}
+
if sec.HasKey("PASSWD") && !sec.HasKey("PASSWORD") {
- IncomingEmail.Password = sec.Key("PASSWD").String()
+ sec.Key("PASSWORD").SetValue(sec.Key("PASSWD").String())
}
+ if sec.HasKey("PASSWD_URI") && !sec.HasKey("PASSWORD_URI") {
+ sec.Key("PASSWORD_URI").SetValue(sec.Key("PASSWD_URI").String())
+ }
+ IncomingEmail.Password = loadSecret(sec, "PASSWORD_URI", "PASSWORD")
// Infer Port if not set
if IncomingEmail.Port == 0 {
diff --git a/modules/setting/incoming_email_test.go b/modules/setting/incoming_email_test.go
index 6d181cae3c..4ea740bafd 100644
--- a/modules/setting/incoming_email_test.go
+++ b/modules/setting/incoming_email_test.go
@@ -4,6 +4,8 @@
package setting
import (
+ "os"
+ "path/filepath"
"testing"
"github.com/stretchr/testify/assert"
@@ -35,6 +37,22 @@ func Test_loadIncomingEmailFrom(t *testing.T) {
assert.Equal(t, "y0u'll n3v3r gUess th1S!!1", IncomingEmail.Password)
})
+ t.Run("Secrets", func(t *testing.T) {
+ uri := filepath.Join(t.TempDir(), "email_incoming_password")
+
+ if err := os.WriteFile(uri, []byte("th1S gUess n3v3r y0u'll!!1"), 0o644); err != nil {
+ t.Fatal(err)
+ }
+
+ cfg, sec := makeBaseConfig()
+ sec.NewKey("PASSWORD_URI", "file:"+uri)
+
+ IncomingEmail.Password = ""
+ loadIncomingEmailFrom(cfg)
+
+ assert.Equal(t, "th1S gUess n3v3r y0u'll!!1", IncomingEmail.Password)
+ })
+
t.Run("Port settings", func(t *testing.T) {
t.Run("no port, no tls", func(t *testing.T) {
defer resetIncomingEmailPort()()
diff --git a/modules/setting/log.go b/modules/setting/log.go
index 0747ac4dac..6d069d0e9c 100644
--- a/modules/setting/log.go
+++ b/modules/setting/log.go
@@ -133,6 +133,7 @@ func loadLogModeByName(rootCfg ConfigProvider, loggerName, modeName string) (wri
writerMode.StacktraceLevel = log.LevelFromString(ConfigInheritedKeyString(sec, "STACKTRACE_LEVEL", Log.StacktraceLogLevel.String()))
writerMode.Prefix = ConfigInheritedKeyString(sec, "PREFIX")
writerMode.Expression = ConfigInheritedKeyString(sec, "EXPRESSION")
+ writerMode.Exclusion = ConfigInheritedKeyString(sec, "EXCLUSION")
// flags are updated and set below
switch writerType {
diff --git a/modules/setting/log_test.go b/modules/setting/log_test.go
index eda6dc36af..223bd68285 100644
--- a/modules/setting/log_test.go
+++ b/modules/setting/log_test.go
@@ -44,6 +44,7 @@ func TestLogConfigDefault(t *testing.T) {
"BufferLen": 10000,
"Colorize": false,
"Expression": "",
+ "Exclusion": "",
"Flags": "stdflags",
"Level": "info",
"Prefix": "",
@@ -83,6 +84,7 @@ logger.xorm.MODE =
"BufferLen": 10000,
"Colorize": false,
"Expression": "",
+ "Exclusion": "",
"Flags": "stdflags",
"Level": "info",
"Prefix": "",
@@ -121,6 +123,7 @@ MODE = console
"BufferLen": 10000,
"Colorize": false,
"Expression": "",
+ "Exclusion": "",
"Flags": "stdflags",
"Level": "info",
"Prefix": "",
@@ -168,6 +171,7 @@ ACCESS = file
"BufferLen": 10000,
"Colorize": false,
"Expression": "",
+ "Exclusion": "",
"Flags": "stdflags",
"Level": "info",
"Prefix": "",
@@ -191,6 +195,7 @@ ACCESS = file
"BufferLen": 10000,
"Colorize": false,
"Expression": "",
+ "Exclusion": "",
"Flags": "none",
"Level": "info",
"Prefix": "",
@@ -257,6 +262,7 @@ STDERR = true
"BufferLen": 10000,
"Colorize": false,
"Expression": "",
+ "Exclusion": "",
"Flags": "stdflags",
"Level": "warn",
"Prefix": "",
@@ -270,6 +276,7 @@ STDERR = true
"BufferLen": 10000,
"Colorize": false,
"Expression": "",
+ "Exclusion": "",
"Flags": "stdflags",
"Level": "error",
"Prefix": "",
@@ -287,6 +294,7 @@ STDERR = true
"BufferLen": 10000,
"Colorize": false,
"Expression": "",
+ "Exclusion": "",
"Flags": "none",
"Level": "warn",
"Prefix": "",
@@ -323,6 +331,7 @@ MODE = file
LEVEL = error
STACKTRACE_LEVEL = fatal
EXPRESSION = filter
+EXCLUSION = not
FLAGS = medfile
PREFIX = "[Prefix] "
FILE_NAME = file-xxx.log
@@ -341,6 +350,7 @@ COMPRESSION_LEVEL = 4
"BufferLen": 10,
"Colorize": false,
"Expression": "",
+ "Exclusion": "",
"Flags": "stdflags",
"Level": "info",
"Prefix": "",
@@ -360,6 +370,7 @@ COMPRESSION_LEVEL = 4
"BufferLen": 10,
"Colorize": false,
"Expression": "filter",
+ "Exclusion": "not",
"Flags": "medfile",
"Level": "error",
"Prefix": "[Prefix] ",
diff --git a/modules/setting/mailer.go b/modules/setting/mailer.go
index 9c004c6ce0..b43484a90f 100644
--- a/modules/setting/mailer.go
+++ b/modules/setting/mailer.go
@@ -147,6 +147,10 @@ func loadMailerFrom(rootCfg ConfigProvider) {
if sec.HasKey("PASSWORD") && !sec.HasKey("PASSWD") {
sec.Key("PASSWD").SetValue(sec.Key("PASSWORD").String())
}
+ if sec.HasKey("PASSWORD_URI") && !sec.HasKey("PASSWD_URI") {
+ sec.Key("PASSWD_URI").SetValue(sec.Key("PASSWORD_URI").String())
+ }
+ sec.Key("PASSWD").SetValue(loadSecret(sec, "PASSWD_URI", "PASSWD"))
// Set default values & validate
sec.Key("NAME").MustString(AppName)
diff --git a/modules/setting/mailer_test.go b/modules/setting/mailer_test.go
index 4523cc91dd..47eaf3ffbb 100644
--- a/modules/setting/mailer_test.go
+++ b/modules/setting/mailer_test.go
@@ -4,6 +4,8 @@
package setting
import (
+ "os"
+ "path/filepath"
"testing"
"github.com/stretchr/testify/assert"
@@ -52,6 +54,24 @@ func Test_loadMailerFrom(t *testing.T) {
assert.Equal(t, "y0u'll n3v3r gUess th1S!!1", MailService.Passwd)
})
+ t.Run("Secrets", func(t *testing.T) {
+ uri := filepath.Join(t.TempDir(), "mailer_passwd")
+
+ if err := os.WriteFile(uri, []byte("th1S gUess n3v3r y0u'll!!1"), 0o644); err != nil {
+ t.Fatal(err)
+ }
+
+ cfg, _ := NewConfigProviderFromData("")
+ sec := cfg.Section("mailer")
+ sec.NewKey("ENABLED", "true")
+ sec.NewKey("PASSWD_URI", "file:"+uri)
+
+ MailService.Passwd = ""
+ loadMailerFrom(cfg)
+
+ assert.Equal(t, "th1S gUess n3v3r y0u'll!!1", MailService.Passwd)
+ })
+
t.Run("sendmail argument sanitization", func(t *testing.T) {
cfg, _ := NewConfigProviderFromData("")
sec := cfg.Section("mailer")
diff --git a/modules/structs/activitypub.go b/modules/structs/activitypub.go
index 117eb0bed2..0cc257ff95 100644
--- a/modules/structs/activitypub.go
+++ b/modules/structs/activitypub.go
@@ -1,4 +1,5 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package structs
@@ -7,3 +8,15 @@ package structs
type ActivityPub struct {
Context string `json:"@context"`
}
+
+type APRemoteFollowOption struct {
+ Target string `json:"target"`
+}
+
+type APPersonFollowItem struct {
+ ActorID string `json:"actor_id"`
+ Note string `json:"note"`
+
+ OriginalURL string `json:"original_url"`
+ OriginalItem string `json:"original_item"`
+}
diff --git a/modules/structs/attachment.go b/modules/structs/attachment.go
index 0a3d4140c2..746f618cf0 100644
--- a/modules/structs/attachment.go
+++ b/modules/structs/attachment.go
@@ -22,6 +22,12 @@ type Attachment struct {
Type string `json:"type"`
}
+// WebAttachment the generic attachment with mime type
+type WebAttachment struct {
+ *Attachment
+ MimeType string `json:"mime_type"`
+}
+
// EditAttachmentOptions options for editing attachments
// swagger:model
type EditAttachmentOptions struct {
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 02b175e6f6..42b4bad83c 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -188,6 +188,7 @@ func NewFuncMap() template.FuncMap {
"RenderMarkdownToHtml": RenderMarkdownToHtml,
"RenderLabel": RenderLabel,
"RenderLabels": RenderLabels,
+ "RenderUser": RenderUser,
"RenderReviewRequest": RenderReviewRequest,
// -----------------------------------------------------------------
diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go
index a4d7a82eea..48f4eb04a3 100644
--- a/modules/templates/util_render.go
+++ b/modules/templates/util_render.go
@@ -7,6 +7,7 @@ import (
"context"
"encoding/hex"
"fmt"
+ "html"
"html/template"
"math"
"net/url"
@@ -15,6 +16,7 @@ import (
"unicode"
issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
"forgejo.org/modules/emoji"
"forgejo.org/modules/log"
"forgejo.org/modules/markup"
@@ -26,7 +28,7 @@ import (
// RenderCommitMessage renders commit message with XSS-safe and special links.
func RenderCommitMessage(ctx context.Context, msg string, metas map[string]string) template.HTML {
- cleanMsg := template.HTMLEscapeString(msg)
+ cleanMsg := html.EscapeString(msg)
// we can safely assume that it will not return any error, since there
// shouldn't be any special HTML.
fullMessage, err := markup.RenderCommitMessage(&markup.RenderContext{
@@ -63,7 +65,7 @@ func RenderCommitMessageLinkSubject(ctx context.Context, msg, urlDefault string,
Ctx: ctx,
DefaultLink: urlDefault,
Metas: metas,
- }, template.HTMLEscapeString(msgLine))
+ }, html.EscapeString(msgLine))
if err != nil {
log.Error("RenderCommitMessageSubject: %v", err)
return template.HTML("")
@@ -88,7 +90,7 @@ func RenderCommitBody(ctx context.Context, msg string, metas map[string]string)
renderedMessage, err := markup.RenderCommitMessage(&markup.RenderContext{
Ctx: ctx,
Metas: metas,
- }, template.HTMLEscapeString(msgLine))
+ }, html.EscapeString(msgLine))
if err != nil {
log.Error("RenderCommitMessage: %v", err)
return ""
@@ -122,7 +124,7 @@ func RenderIssueTitle(ctx context.Context, text string, metas map[string]string)
renderedText, err := markup.RenderIssueTitle(&markup.RenderContext{
Ctx: ctx,
Metas: metas,
- }, template.HTMLEscapeString(text))
+ }, html.EscapeString(text))
if err != nil {
log.Error("RenderIssueTitle: %v", err)
return template.HTML("")
@@ -132,7 +134,7 @@ func RenderIssueTitle(ctx context.Context, text string, metas map[string]string)
// RenderRefIssueTitle renders referenced issue/pull title with defined post processors
func RenderRefIssueTitle(ctx context.Context, text string) template.HTML {
- renderedText, err := markup.RenderRefIssueTitle(&markup.RenderContext{Ctx: ctx}, template.HTMLEscapeString(text))
+ renderedText, err := markup.RenderRefIssueTitle(&markup.RenderContext{Ctx: ctx}, html.EscapeString(text))
if err != nil {
log.Error("RenderRefIssueTitle: %v", err)
return ""
@@ -150,7 +152,7 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m
labelScope = label.ExclusiveScope()
)
- description := emoji.ReplaceAliases(template.HTMLEscapeString(label.Description))
+ description := emoji.ReplaceAliases(html.EscapeString(label.Description))
if label.IsArchived() {
archivedCSSClass = "archived-label"
@@ -212,7 +214,7 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m
// RenderEmoji renders html text with emoji post processors
func RenderEmoji(ctx context.Context, text string) template.HTML {
renderedText, err := markup.RenderEmoji(&markup.RenderContext{Ctx: ctx},
- template.HTMLEscapeString(text))
+ html.EscapeString(text))
if err != nil {
log.Error("RenderEmoji: %v", err)
return template.HTML("")
@@ -263,10 +265,20 @@ func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issu
return template.HTML(htmlCode)
}
+func RenderUser(ctx context.Context, user user_model.User) template.HTML {
+ if user.ID > 0 {
+ return template.HTML(fmt.Sprintf(
+ "%s",
+ user.HomeLink(), html.EscapeString(user.GetDisplayName())))
+ }
+ return template.HTML(fmt.Sprintf("%s",
+ html.EscapeString(user.GetDisplayName())))
+}
+
func RenderReviewRequest(users []issues_model.RequestReviewTarget) template.HTML {
usernames := make([]string, 0, len(users))
for _, user := range users {
- usernames = append(usernames, template.HTMLEscapeString(user.Name()))
+ usernames = append(usernames, html.EscapeString(user.Name()))
}
htmlCode := ``
diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go
index 62e063213c..a5fb18642a 100644
--- a/modules/templates/util_render_test.go
+++ b/modules/templates/util_render_test.go
@@ -11,6 +11,9 @@ import (
"forgejo.org/models/db"
issues_model "forgejo.org/models/issues"
"forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"forgejo.org/modules/translation"
"github.com/stretchr/testify/assert"
@@ -215,9 +218,51 @@ func TestRenderLabels(t *testing.T) {
tr := &translation.MockLocale{}
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
+ labelScoped := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 7})
+ labelMalicious := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 11})
+ labelArchived := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 12})
- assert.Contains(t, RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", false),
- "user2/repo1/issues?labels=1")
- assert.Contains(t, RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", true),
- "user2/repo1/pulls?labels=1")
+ rendered := RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", false)
+ assert.Contains(t, rendered, "user2/repo1/issues?labels=1")
+ assert.Contains(t, rendered, ">label1<")
+ assert.Contains(t, rendered, "title='First label'")
+ rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", true)
+ assert.Contains(t, rendered, "user2/repo1/pulls?labels=1")
+ assert.Contains(t, rendered, ">label1<")
+ rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelScoped}, "user2/repo1", false)
+ assert.Contains(t, rendered, "user2/repo1/issues?labels=7")
+ assert.Contains(t, rendered, ">scope<")
+ assert.Contains(t, rendered, ">label1<")
+ rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelMalicious}, "user2/repo1", false)
+ assert.Contains(t, rendered, "user2/repo1/issues?labels=11")
+ assert.Contains(t, rendered, "> <script>malicious</script> <")
+ assert.Contains(t, rendered, ">'?&<")
+ assert.Contains(t, rendered, "title='Malicious label ' <script>malicious</script>'")
+ rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelArchived}, "user2/repo1", false)
+ assert.Contains(t, rendered, "user2/repo1/issues?labels=12")
+ assert.Contains(t, rendered, ">archived label<><")
+ assert.Contains(t, rendered, "title='repo.issues.archived_label_description'")
+}
+
+func TestRenderUser(t *testing.T) {
+ unittest.PrepareTestEnv(t)
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
+ ghost := user_model.NewGhostUser()
+
+ assert.Contains(t, RenderUser(db.DefaultContext, *user),
+ "user2")
+ assert.Contains(t, RenderUser(db.DefaultContext, *org),
+ "org3")
+ assert.Contains(t, RenderUser(db.DefaultContext, *ghost),
+ "Ghost")
+
+ defer test.MockVariableValue(&setting.UI.DefaultShowFullName, true)()
+ assert.Contains(t, RenderUser(db.DefaultContext, *user),
+ "< U<se>r Tw<o > ><")
+ assert.Contains(t, RenderUser(db.DefaultContext, *org),
+ "<<<< >> >> > >> > >>> >>")
+ assert.Contains(t, RenderUser(db.DefaultContext, *ghost),
+ "Ghost")
}
diff --git a/modules/test/distant_federation_server_mock.go b/modules/test/distant_federation_server_mock.go
index 9bd908e2b9..ea8a69e9b4 100644
--- a/modules/test/distant_federation_server_mock.go
+++ b/modules/test/distant_federation_server_mock.go
@@ -10,56 +10,79 @@ import (
"net/http/httptest"
"strings"
"testing"
+
+ "forgejo.org/modules/util"
)
type FederationServerMockPerson struct {
- ID int64
- Name string
- PubKey string
+ ID int64
+ Name string
+ PubKey string
+ PrivKey string
}
type FederationServerMockRepository struct {
ID int64
}
+type ApActorMock struct {
+ PrivKey string
+ PubKey string
+}
type FederationServerMock struct {
+ ApActor ApActorMock
Persons []FederationServerMockPerson
Repositories []FederationServerMockRepository
LastPost string
}
func NewFederationServerMockPerson(id int64, name string) FederationServerMockPerson {
+ priv, pub, _ := util.GenerateKeyPair(3072)
return FederationServerMockPerson{
- ID: id,
- Name: name,
- PubKey: `"-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA18H5s7N6ItZUAh9tneII\nIuZdTTa3cZlLa/9ejWAHTkcp3WLW+/zbsumlMrWYfBy2/yTm56qasWt38iY4D6ul\n` +
- `CPiwhAqX3REvVq8tM79a2CEqZn9ka6vuXoDgBg/sBf/BUWqf7orkjUXwk/U0Egjf\nk5jcurF4vqf1u+rlAHH37dvSBaDjNj6Qnj4OP12bjfaY/yvs7+jue/eNXFHjzN4E\n` +
- `T2H4B/yeKTJ4UuAwTlLaNbZJul2baLlHelJPAsxiYaziVuV5P+IGWckY6RSerRaZ\nAkc4mmGGtjAyfN9aewe+lNVfwS7ElFx546PlLgdQgjmeSwLX8FWxbPE5A/PmaXCs\n` +
- `nx+nou+3dD7NluULLtdd7K+2x02trObKXCAzmi5/Dc+yKTzpFqEz+hLNCz7TImP/\ncK//NV9Q+X67J9O27baH9R9ZF4zMw8rv2Pg0WLSw1z7lLXwlgIsDapeMCsrxkVO4\n` +
- `LXX5AQ1xQNtlssnVoUBqBrvZsX2jUUKUocvZqMGuE4hfAgMBAAE=\n-----END PUBLIC KEY-----\n"`,
+ ID: id,
+ Name: name,
+ PubKey: pub,
+ PrivKey: priv,
}
}
+func (p *FederationServerMockPerson) KeyID(host string) string {
+ return fmt.Sprintf("%[1]v/api/v1/activitypub/user-id/%[2]v#main-key", host, p.ID)
+}
+
func NewFederationServerMockRepository(id int64) FederationServerMockRepository {
return FederationServerMockRepository{
ID: id,
}
}
+func NewApActorMock() ApActorMock {
+ priv, pub, _ := util.GenerateKeyPair(1024)
+ return ApActorMock{
+ PrivKey: priv,
+ PubKey: pub,
+ }
+}
+
+func (u *ApActorMock) KeyID(host string) string {
+ return fmt.Sprintf("%[1]v/api/v1/activitypub/actor#main-key", host)
+}
+
func (p FederationServerMockPerson) marshal(host string) string {
return fmt.Sprintf(`{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],`+
- `"id":"http://%[1]v/api/activitypub/user-id/%[2]v",`+
+ `"id":"http://%[1]v/api/v1/activitypub/user-id/%[2]v",`+
`"type":"Person",`+
`"icon":{"type":"Image","mediaType":"image/png","url":"http://%[1]v/avatars/1bb05d9a5f6675ed0272af9ea193063c"},`+
`"url":"http://%[1]v/%[2]v",`+
- `"inbox":"http://%[1]v/api/activitypub/user-id/%[2]v/inbox",`+
- `"outbox":"http://%[1]v/api/activitypub/user-id/%[2]v/outbox",`+
+ `"inbox":"http://%[1]v/api/v1/activitypub/user-id/%[2]v/inbox",`+
+ `"outbox":"http://%[1]v/api/v1/activitypub/user-id/%[2]v/outbox",`+
`"preferredUsername":"%[3]v",`+
- `"publicKey":{"id":"http://%[1]v/api/activitypub/user-id/%[2]v#main-key",`+
- `"owner":"http://%[1]v/api/activitypub/user-id/%[2]v",`+
- `"publicKeyPem":%[4]v}}`, host, p.ID, p.Name, p.PubKey)
+ `"publicKey":{"id":"http://%[1]v/api/v1/activitypub/user-id/%[2]v#main-key",`+
+ `"owner":"http://%[1]v/api/v1/activitypub/user-id/%[2]v",`+
+ `"publicKeyPem":%[4]q}}`, host, p.ID, p.Name, p.PubKey)
}
func NewFederationServerMock() *FederationServerMock {
return &FederationServerMock{
+ ApActor: NewApActorMock(),
Persons: []FederationServerMockPerson{
NewFederationServerMockPerson(15, "stargoose1"),
NewFederationServerMockPerson(30, "stargoose2"),
@@ -71,8 +94,18 @@ func NewFederationServerMock() *FederationServerMock {
}
}
+func (mock *FederationServerMock) recordLastPost(t *testing.T, req *http.Request) {
+ buf := new(strings.Builder)
+ _, err := io.Copy(buf, req.Body)
+ if err != nil {
+ t.Errorf("Error reading body: %q", err)
+ }
+ mock.LastPost = strings.ReplaceAll(buf.String(), req.Host, "DISTANT_FEDERATION_HOST")
+}
+
func (mock *FederationServerMock) DistantServer(t *testing.T) *httptest.Server {
federatedRoutes := http.NewServeMux()
+
federatedRoutes.HandleFunc("/.well-known/nodeinfo",
func(res http.ResponseWriter, req *http.Request) {
// curl -H "Accept: application/json" https://federated-repo.prod.meissa.de/.well-known/nodeinfo
@@ -87,30 +120,28 @@ func (mock *FederationServerMock) DistantServer(t *testing.T) *httptest.Server {
`"protocols":["activitypub"],"services":{"inbound":[],"outbound":["rss2.0"]},`+
`"openRegistrations":true,"usage":{"users":{"total":14,"activeHalfyear":2}},"metadata":{}}`)
})
+
for _, person := range mock.Persons {
federatedRoutes.HandleFunc(fmt.Sprintf("/api/v1/activitypub/user-id/%v", person.ID),
func(res http.ResponseWriter, req *http.Request) {
// curl -H "Accept: application/json" https://federated-repo.prod.meissa.de/api/v1/activitypub/user-id/2
fmt.Fprint(res, person.marshal(req.Host))
})
- }
- for _, repository := range mock.Repositories {
- federatedRoutes.HandleFunc(fmt.Sprintf("/api/v1/activitypub/repository-id/%v/inbox", repository.ID),
+ federatedRoutes.HandleFunc(fmt.Sprintf("POST /api/v1/activitypub/user-id/%v/inbox", person.ID),
func(res http.ResponseWriter, req *http.Request) {
- if req.Method != "POST" {
- t.Errorf("POST expected at: %q", req.URL.EscapedPath())
- }
- buf := new(strings.Builder)
- _, err := io.Copy(buf, req.Body)
- if err != nil {
- t.Errorf("Error reading body: %q", err)
- }
- mock.LastPost = buf.String()
+ mock.recordLastPost(t, req)
+ })
+ }
+
+ for _, repository := range mock.Repositories {
+ federatedRoutes.HandleFunc(fmt.Sprintf("POST /api/v1/activitypub/repository-id/%v/inbox", repository.ID),
+ func(res http.ResponseWriter, req *http.Request) {
+ mock.recordLastPost(t, req)
})
}
federatedRoutes.HandleFunc("/",
func(res http.ResponseWriter, req *http.Request) {
- t.Errorf("Unhandled request: %q", req.URL.EscapedPath())
+ t.Errorf("Unhandled %v request: %q", req.Method, req.URL.EscapedPath())
})
federatedSrv := httptest.NewServer(federatedRoutes)
return federatedSrv
diff --git a/modules/typesniffer/typesniffer.go b/modules/typesniffer/typesniffer.go
index 262feb2b05..8cb1513a88 100644
--- a/modules/typesniffer/typesniffer.go
+++ b/modules/typesniffer/typesniffer.go
@@ -124,7 +124,7 @@ func (ct SniffedType) GetMimeType() string {
}
// DetectContentType extends http.DetectContentType with more content types. Defaults to text/unknown if input is empty.
-func DetectContentType(data []byte) SniffedType {
+func DetectContentType(data []byte, filename string) SniffedType {
if len(data) == 0 {
return SniffedType{"text/unknown"}
}
@@ -176,6 +176,13 @@ func DetectContentType(data []byte) SniffedType {
}
}
+ if ct == "application/octet-stream" &&
+ filename != "" &&
+ !strings.HasSuffix(strings.ToUpper(filename), ".LCOM") &&
+ bytes.Contains(data, []byte("(DEFINE-FILE-INFO ")) {
+ ct = "text/vnd.interlisp"
+ }
+
// GLTF is unsupported by http.DetectContentType
// hexdump -n 4 -C glTF.glb
if bytes.HasPrefix(data, []byte("glTF")) {
@@ -186,7 +193,7 @@ func DetectContentType(data []byte) SniffedType {
}
// DetectContentTypeFromReader guesses the content type contained in the reader.
-func DetectContentTypeFromReader(r io.Reader) (SniffedType, error) {
+func DetectContentTypeFromReader(r io.Reader, filename string) (SniffedType, error) {
buf := make([]byte, sniffLen)
n, err := util.ReadAtMost(r, buf)
if err != nil {
@@ -194,5 +201,5 @@ func DetectContentTypeFromReader(r io.Reader) (SniffedType, error) {
}
buf = buf[:n]
- return DetectContentType(buf), nil
+ return DetectContentType(buf, filename), nil
}
diff --git a/modules/typesniffer/typesniffer_test.go b/modules/typesniffer/typesniffer_test.go
index 176d3658bb..d2b7ed4f21 100644
--- a/modules/typesniffer/typesniffer_test.go
+++ b/modules/typesniffer/typesniffer_test.go
@@ -16,63 +16,63 @@ import (
func TestDetectContentTypeLongerThanSniffLen(t *testing.T) {
// Pre-condition: Shorter than sniffLen detects SVG.
- assert.Equal(t, "image/svg+xml", DetectContentType([]byte(``)).contentType)
+ assert.Equal(t, "image/svg+xml", DetectContentType([]byte(``), "").contentType)
// Longer than sniffLen detects something else.
- assert.NotEqual(t, "image/svg+xml", DetectContentType([]byte(``)).contentType)
+ assert.NotEqual(t, "image/svg+xml", DetectContentType([]byte(``), "").contentType)
}
func TestIsTextFile(t *testing.T) {
- assert.True(t, DetectContentType([]byte{}).IsText())
- assert.True(t, DetectContentType([]byte("lorem ipsum")).IsText())
+ assert.True(t, DetectContentType([]byte{}, "").IsText())
+ assert.True(t, DetectContentType([]byte("lorem ipsum"), "").IsText())
}
func TestIsSvgImage(t *testing.T) {
- assert.True(t, DetectContentType([]byte("")).IsSvgImage())
- assert.True(t, DetectContentType([]byte(" ")).IsSvgImage())
- assert.True(t, DetectContentType([]byte(``)).IsSvgImage())
- assert.True(t, DetectContentType([]byte(``)).IsSvgImage())
+ assert.True(t, DetectContentType([]byte(""), "").IsSvgImage())
+ assert.True(t, DetectContentType([]byte(" "), "").IsSvgImage())
+ assert.True(t, DetectContentType([]byte(``), "").IsSvgImage())
+ assert.True(t, DetectContentType([]byte(``), "").IsSvgImage())
assert.True(t, DetectContentType([]byte(`
- `)).IsSvgImage())
+ `), "").IsSvgImage())
assert.True(t, DetectContentType([]byte(`
- `)).IsSvgImage())
+ `), "").IsSvgImage())
assert.True(t, DetectContentType([]byte(`
- `)).IsSvgImage())
+ `), "").IsSvgImage())
assert.True(t, DetectContentType([]byte(`
- `)).IsSvgImage())
+ `), "").IsSvgImage())
assert.True(t, DetectContentType([]byte(`
- `)).IsSvgImage())
+ `), "").IsSvgImage())
assert.True(t, DetectContentType([]byte(`
- `)).IsSvgImage())
+ `), "").IsSvgImage())
assert.True(t, DetectContentType([]byte(`
- `)).IsSvgImage())
+ `), "").IsSvgImage())
assert.True(t, DetectContentType([]byte(`
- `)).IsSvgImage())
+ `), "").IsSvgImage())
// the DetectContentType should work for incomplete data, because only beginning bytes are used for detection
- assert.True(t, DetectContentType([]byte(`