feat: update gitea vendor
runner nix smoke / nix label and flake smoke (push) Failing after 1m28s

This commit is contained in:
2026-09-26 21:18:24 +00:00
parent c439c1b948
commit d9b2a4e787
3538 changed files with 116131 additions and 44340 deletions
+12 -18
View File
@@ -8,16 +8,16 @@ import (
"fmt"
"time"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"gitea.dev/models/db"
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unit"
user_model "gitea.dev/models/user"
"gitea.dev/modules/container"
"gitea.dev/modules/git"
"gitea.dev/modules/log"
"gitea.dev/modules/optional"
"gitea.dev/modules/timeutil"
"gitea.dev/modules/util"
"xorm.io/builder"
)
@@ -261,7 +261,7 @@ func UpdateBranch(ctx context.Context, repoID, pusherID int64, branchName string
Cols("commit_id, commit_message, pusher_id, commit_time, is_deleted, updated_unix").
Update(&Branch{
CommitID: commit.ID.String(),
CommitMessage: commit.Summary(),
CommitMessage: commit.MessageTitle(),
PusherID: pusherID,
CommitTime: timeutil.TimeStamp(commit.Committer.When.Unix()),
IsDeleted: false,
@@ -323,13 +323,7 @@ type RenamedBranch struct {
// FindRenamedBranch check if a branch was renamed
func FindRenamedBranch(ctx context.Context, repoID int64, from string) (branch *RenamedBranch, exist bool, err error) {
branch = &RenamedBranch{
RepoID: repoID,
From: from,
}
exist, err = db.GetEngine(ctx).Get(branch)
return branch, exist, err
return db.Get[RenamedBranch](ctx, builder.Eq{"repo_id": repoID, "`from`": from})
}
// RenameBranch rename a branch
+5 -24
View File
@@ -6,11 +6,10 @@ package git
import (
"context"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/optional"
"gitea.dev/models/db"
user_model "gitea.dev/models/user"
"gitea.dev/modules/container"
"gitea.dev/modules/optional"
"xorm.io/builder"
)
@@ -60,24 +59,6 @@ func (branches BranchList) LoadPusher(ctx context.Context) error {
return nil
}
func (branches BranchList) LoadRepo(ctx context.Context) error {
ids := container.FilterSlice(branches, func(branch *Branch) (int64, bool) {
return branch.RepoID, branch.RepoID > 0 && branch.Repo == nil
})
reposMap := make(map[int64]*repo_model.Repository, len(ids))
if err := db.GetEngine(ctx).In("id", ids).Find(&reposMap); err != nil {
return err
}
for _, branch := range branches {
if branch.RepoID <= 0 || branch.Repo != nil {
continue
}
branch.Repo = reposMap[branch.RepoID]
}
return nil
}
type FindBranchOptions struct {
db.ListOptions
RepoID int64
@@ -120,7 +101,7 @@ func (opts FindBranchOptions) ToOrders() string {
func FindBranchNames(ctx context.Context, opts FindBranchOptions) ([]string, error) {
sess := db.GetEngine(ctx).Select("name").Where(opts.ToConds())
if opts.PageSize > 0 && !opts.IsListAll() {
sess = db.SetSessionPagination(sess, &opts.ListOptions)
db.SetSessionPagination(sess, &opts.ListOptions)
}
var branches []string
+10 -10
View File
@@ -8,15 +8,15 @@ import (
"testing"
"time"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/timeutil"
"gitea.dev/models/db"
git_model "gitea.dev/models/git"
issues_model "gitea.dev/models/issues"
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unittest"
user_model "gitea.dev/models/user"
"gitea.dev/modules/git"
"gitea.dev/modules/optional"
"gitea.dev/modules/timeutil"
"github.com/stretchr/testify/assert"
)
@@ -36,7 +36,7 @@ func TestAddDeletedBranch(t *testing.T) {
commit := &git.Commit{
ID: git.MustIDFromString(secondBranch.CommitID),
CommitMessage: secondBranch.CommitMessage,
CommitMessage: git.CommitMessage{MessageRaw: secondBranch.CommitMessage},
Committer: &git.Signature{
When: secondBranch.CommitTime.AsLocalTime(),
},
@@ -13,19 +13,19 @@ import (
"strings"
"time"
asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/commitstatus"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/translation"
asymkey_model "gitea.dev/models/asymkey"
"gitea.dev/models/db"
repo_model "gitea.dev/models/repo"
user_model "gitea.dev/models/user"
"gitea.dev/modules/commitstatus"
"gitea.dev/modules/git"
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
"gitea.dev/modules/timeutil"
"gitea.dev/modules/translation"
"gitea.dev/modules/util"
"xorm.io/builder"
"xorm.io/xorm"
)
// CommitStatus holds a single Status of a single Commit
@@ -120,7 +120,7 @@ WHEN NOT MATCHED
func GetNextCommitStatusIndex(ctx context.Context, repoID int64, sha string) (int64, error) {
_, err := git.NewIDFromString(sha)
if err != nil {
return 0, git.ErrInvalidSHA{SHA: sha}
return 0, util.NewInvalidArgumentErrorf("invalid sha: %v", err)
}
switch {
@@ -329,7 +329,7 @@ type CommitStatusIndex struct {
MaxIndex int64 `xorm:"index"`
}
func makeRepoCommitQuery(ctx context.Context, repoID int64, sha string) *xorm.Session {
func makeRepoCommitQuery(ctx context.Context, repoID int64, sha string) db.Session {
return db.GetEngine(ctx).Table(&CommitStatus{}).
Where("repo_id = ?", repoID).And("sha = ?", sha)
}
@@ -337,12 +337,10 @@ func makeRepoCommitQuery(ctx context.Context, repoID int64, sha string) *xorm.Se
// GetLatestCommitStatus returns all statuses with a unique context for a given commit.
func GetLatestCommitStatus(ctx context.Context, repoID int64, sha string, listOptions db.ListOptions) ([]*CommitStatus, error) {
indices := make([]int64, 0, 10)
sess := makeRepoCommitQuery(ctx, repoID, sha).
Select("max( `index` ) as `index`").
GroupBy("context_hash").
OrderBy("max( `index` ) desc")
sess := makeRepoCommitQuery(ctx, repoID, sha)
sess.Select("max( `index` ) as `index`").GroupBy("context_hash").OrderBy("max( `index` ) desc")
if !listOptions.IsListAll() {
sess = db.SetSessionPagination(sess, &listOptions)
db.SetSessionPagination(sess, &listOptions)
}
if err := sess.Find(&indices); err != nil {
return nil, err
@@ -372,7 +370,7 @@ func GetLatestCommitStatusForPairs(ctx context.Context, repoSHAs []RepoSHA) (map
results := make([]result, 0, len(repoSHAs))
getBase := func() *xorm.Session {
getBase := func() db.Session {
return db.GetEngine(ctx).Table(&CommitStatus{})
}
@@ -425,7 +423,7 @@ func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, co
SHA string
}
getBase := func() *xorm.Session {
getBase := func() db.Session {
return db.GetEngine(ctx).Table(&CommitStatus{}).Where("repo_id = ?", repoID)
}
results := make([]result, 0, len(commitIDs))
@@ -508,13 +506,19 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error {
opts.CommitStatus.Description = strings.TrimSpace(opts.CommitStatus.Description)
opts.CommitStatus.Context = strings.TrimSpace(opts.CommitStatus.Context)
opts.CommitStatus.TargetURL = strings.TrimSpace(opts.CommitStatus.TargetURL)
opts.CommitStatus.ContextHash = strings.TrimSpace(opts.CommitStatus.ContextHash)
opts.CommitStatus.SHA = opts.SHA.String()
opts.CommitStatus.CreatorID = opts.Creator.ID
opts.CommitStatus.RepoID = opts.Repo.ID
opts.CommitStatus.Index = idx
log.Debug("NewCommitStatus[%s, %s]: %d", opts.Repo.FullName(), opts.SHA, opts.CommitStatus.Index)
opts.CommitStatus.ContextHash = hashCommitStatusContext(opts.CommitStatus.Context)
// Callers may pre-compute a ContextHash to keep entries that share a
// human-readable Context separated (e.g. two workflow files with the
// same `name:` — issue #35699). Only derive from Context when unset.
if opts.CommitStatus.ContextHash == "" {
opts.CommitStatus.ContextHash = HashCommitStatusContext(opts.CommitStatus.Context)
}
// Insert new CommitStatus
if err = db.Insert(ctx, opts.CommitStatus); err != nil {
@@ -532,8 +536,11 @@ type SignCommitWithStatuses struct {
*asymkey_model.SignCommit
}
// hashCommitStatusContext hash context
func hashCommitStatusContext(context string) string {
// HashCommitStatusContext returns the sha1 hash used to dedupe commit statuses
// by Context. Callers that need to keep statuses with the same display Context
// separated (e.g. distinct workflow files sharing a `name:`) can mix extra
// disambiguating data into the input.
func HashCommitStatusContext(context string) string {
return fmt.Sprintf("%x", sha1.Sum([]byte(context)))
}
@@ -6,9 +6,9 @@ package git
import (
"context"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/commitstatus"
"code.gitea.io/gitea/modules/setting"
"gitea.dev/models/db"
"gitea.dev/modules/commitstatus"
"gitea.dev/modules/setting"
"xorm.io/builder"
)
@@ -8,14 +8,14 @@ import (
"testing"
"time"
actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/commitstatus"
"code.gitea.io/gitea/modules/gitrepo"
actions_model "gitea.dev/models/actions"
"gitea.dev/models/db"
git_model "gitea.dev/models/git"
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unittest"
user_model "gitea.dev/models/user"
"gitea.dev/modules/commitstatus"
"gitea.dev/modules/gitrepo"
"github.com/stretchr/testify/assert"
)
+15 -13
View File
@@ -7,15 +7,15 @@ import (
"context"
"fmt"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"gitea.dev/models/db"
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unit"
user_model "gitea.dev/models/user"
"gitea.dev/modules/lfs"
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
"gitea.dev/modules/timeutil"
"gitea.dev/modules/util"
"xorm.io/builder"
)
@@ -126,8 +126,7 @@ func GetLFSMetaObjectByOid(ctx context.Context, repoID int64, oid string) (*LFSM
return nil, ErrLFSObjectNotExist
}
m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repoID}
has, err := db.GetEngine(ctx).Get(m)
m, has, err := db.Get[LFSMetaObject](ctx, builder.Eq{"repository_id": repoID, "oid": oid})
if err != nil {
return nil, err
} else if !has {
@@ -196,7 +195,10 @@ func LFSObjectAccessible(ctx context.Context, user *user_model.User, oid string)
count, err := db.GetEngine(ctx).Count(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}})
return count > 0, err
}
cond := repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)
// LFS objects are repository code content, so authorization must require
// Code-unit access; other unit accesses (e.g. Issues) must not authorize
// reuse of an existing LFS object across repositories.
cond := repo_model.AccessibleRepositoryCondition(user, unit.TypeCode)
count, err := db.GetEngine(ctx).Where(cond).Join("INNER", "repository", "`lfs_meta_object`.repository_id = `repository`.id").Count(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}})
return count > 0, err
}
@@ -220,7 +222,7 @@ func LFSAutoAssociate(ctx context.Context, metas []*LFSMetaObject, user *user_mo
newMetas := make([]*LFSMetaObject, 0, len(metas))
cond := builder.In(
"`lfs_meta_object`.repository_id",
builder.Select("`repository`.id").From("repository").Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)),
builder.Select("`repository`.id").From("repository").Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeCode)),
)
if err := db.GetEngine(ctx).Cols("oid").Where(cond).In("oid", oids...).GroupBy("oid").Find(&newMetas); err != nil {
return err
+5 -5
View File
@@ -10,11 +10,11 @@ import (
"strings"
"time"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"gitea.dev/models/db"
repo_model "gitea.dev/models/repo"
user_model "gitea.dev/models/user"
"gitea.dev/modules/setting"
"gitea.dev/modules/util"
)
// LFSLock represents a git lfs lock of repository.
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
"gitea.dev/models/db"
user_model "gitea.dev/models/user"
"gitea.dev/modules/container"
)
// LFSLockList is a list of LFSLock
@@ -8,9 +8,9 @@ import (
"testing"
"time"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unittest"
user_model "gitea.dev/models/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+8 -8
View File
@@ -10,14 +10,14 @@ import (
"testing"
"time"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/timeutil"
"gitea.dev/models/db"
git_model "gitea.dev/models/git"
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unittest"
"gitea.dev/modules/lfs"
"gitea.dev/modules/setting"
"gitea.dev/modules/test"
"gitea.dev/modules/timeutil"
"github.com/stretchr/testify/assert"
)
+4 -4
View File
@@ -6,11 +6,11 @@ package git_test
import (
"testing"
"code.gitea.io/gitea/models/unittest"
"gitea.dev/models/unittest"
_ "code.gitea.io/gitea/models"
_ "code.gitea.io/gitea/models/actions"
_ "code.gitea.io/gitea/models/activities"
_ "gitea.dev/models"
_ "gitea.dev/models/actions"
_ "gitea.dev/models/activities"
)
func TestMain(m *testing.M) {
@@ -9,17 +9,17 @@ import (
"slices"
"strings"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"gitea.dev/models/db"
"gitea.dev/models/organization"
"gitea.dev/models/perm"
access_model "gitea.dev/models/perm/access"
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unit"
user_model "gitea.dev/models/user"
"gitea.dev/modules/glob"
"gitea.dev/modules/log"
"gitea.dev/modules/timeutil"
"gitea.dev/modules/util"
"xorm.io/builder"
)
@@ -43,6 +43,9 @@ type ProtectedBranch struct {
WhitelistDeployKeys bool `xorm:"NOT NULL DEFAULT false"`
MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
EnableBypassAllowlist bool `xorm:"NOT NULL DEFAULT false"`
BypassAllowlistUserIDs []int64 `xorm:"JSON TEXT"`
BypassAllowlistTeamIDs []int64 `xorm:"JSON TEXT"`
CanForcePush bool `xorm:"NOT NULL DEFAULT false"`
EnableForcePushAllowlist bool `xorm:"NOT NULL DEFAULT false"`
ForcePushAllowlistUserIDs []int64 `xorm:"JSON TEXT"`
@@ -204,6 +207,29 @@ func IsUserMergeWhitelisted(ctx context.Context, protectBranch *ProtectedBranch,
return in
}
// CanBypassBranchProtection reports whether the user can bypass branch protection checks (status checks, approvals, protected files)
// Either a repo admin (when not blocked) or a user/team on the bypass allowlist can bypass.
func CanBypassBranchProtection(ctx context.Context, protectBranch *ProtectedBranch, user *user_model.User, isRepoAdmin bool) bool {
if isRepoAdmin && !protectBranch.BlockAdminMergeOverride {
return true
}
if !protectBranch.EnableBypassAllowlist {
return false
}
if slices.Contains(protectBranch.BypassAllowlistUserIDs, user.ID) {
return true
}
if len(protectBranch.BypassAllowlistTeamIDs) == 0 {
return false
}
in, err := organization.IsUserInTeams(ctx, user.ID, protectBranch.BypassAllowlistTeamIDs)
if err != nil {
log.Error("IsUserInTeams failed: userID=%d, repoID=%d, allowlistTeamIDs=%v, err=%v", user.ID, protectBranch.RepoID, protectBranch.BypassAllowlistTeamIDs, err)
return false
}
return in
}
// IsUserOfficialReviewer check if user is official reviewer for the branch (counts towards required approvals)
func IsUserOfficialReviewer(ctx context.Context, protectBranch *ProtectedBranch, user *user_model.User) (bool, error) {
repo, err := repo_model.GetRepositoryByID(ctx, protectBranch.RepoID)
@@ -347,6 +373,9 @@ type WhitelistOptions struct {
ApprovalsUserIDs []int64
ApprovalsTeamIDs []int64
BypassUserIDs []int64
BypassTeamIDs []int64
}
// UpdateProtectBranch saves branch protection options of repository.
@@ -387,6 +416,12 @@ func UpdateProtectBranch(ctx context.Context, repo *repo_model.Repository, prote
}
protectBranch.ApprovalsWhitelistUserIDs = whitelist
whitelist, err = updateUserWhitelist(ctx, repo, protectBranch.BypassAllowlistUserIDs, opts.BypassUserIDs)
if err != nil {
return err
}
protectBranch.BypassAllowlistUserIDs = whitelist
// if the repo is in an organization
whitelist, err = updateTeamWhitelist(ctx, repo, protectBranch.WhitelistTeamIDs, opts.TeamIDs)
if err != nil {
@@ -412,6 +447,12 @@ func UpdateProtectBranch(ctx context.Context, repo *repo_model.Repository, prote
}
protectBranch.ApprovalsWhitelistTeamIDs = whitelist
whitelist, err = updateTeamWhitelist(ctx, repo, protectBranch.BypassAllowlistTeamIDs, opts.BypassTeamIDs)
if err != nil {
return err
}
protectBranch.BypassAllowlistTeamIDs = whitelist
// Looks like it's a new rule
if protectBranch.ID == 0 {
// as it's a new rule and if priority was not set, we need to calc it.
@@ -466,7 +507,7 @@ func updateApprovalWhitelist(ctx context.Context, repo *repo_model.Repository, c
return currentWhitelist, nil
}
prUserIDs, err := access_model.GetUserIDsWithUnitAccess(ctx, repo, perm.AccessModeRead, unit.TypePullRequests)
prUserIDs, err := access_model.GetUserIDsWithAnyUnitAccess(ctx, repo, perm.AccessModeRead, unit.TypePullRequests)
if err != nil {
return nil, err
}
@@ -7,9 +7,9 @@ import (
"context"
"sort"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/optional"
"gitea.dev/models/db"
"gitea.dev/modules/glob"
"gitea.dev/modules/optional"
)
type ProtectedBranchRules []*ProtectedBranch
@@ -6,9 +6,10 @@ package git
import (
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"gitea.dev/models/db"
repo_model "gitea.dev/models/repo"
"gitea.dev/models/unittest"
user_model "gitea.dev/models/user"
"github.com/stretchr/testify/assert"
)
@@ -153,3 +154,51 @@ func TestNewProtectBranchPriority(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, int64(2), savedPB2.Priority)
}
func TestCanBypassBranchProtection(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) // not in team 1
teamMember := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
pb := &ProtectedBranch{
EnableBypassAllowlist: true,
BypassAllowlistUserIDs: []int64{user.ID},
}
testBypass := func(t *testing.T, expected bool, pb *ProtectedBranch, doer *user_model.User, isAdmin bool) {
assert.Equal(t, expected, CanBypassBranchProtection(t.Context(), pb, doer, isAdmin))
}
// User bypasses via explicit allowlist.
testBypass(t, true, pb, user, false)
// Non-admin cannot bypass when allowlist is disabled.
pb.EnableBypassAllowlist = false
testBypass(t, false, pb, user, false)
// Repo admin can bypass independently of allowlist when not blocked.
testBypass(t, true, pb, user, true)
// Admin override block still allows bypass for allowlisted users.
pb.EnableBypassAllowlist = true
pb.BlockAdminMergeOverride = true
testBypass(t, true, pb, user, false)
// admin cannot bypass without allowlist membership.
pb.BypassAllowlistUserIDs = nil
testBypass(t, false, pb, user, true)
// admin can bypass when allowlisted.
pb.BypassAllowlistUserIDs = []int64{user.ID}
testBypass(t, true, pb, user, true)
// User bypasses via team allowlist membership.
pb.EnableBypassAllowlist = true
pb.BlockAdminMergeOverride = false
pb.BypassAllowlistUserIDs = nil
pb.BypassAllowlistTeamIDs = []int64{1} // team 1 contains user 2 in test fixtures
testBypass(t, true, pb, teamMember, false)
// User does not bypass when not in allowlisted teams.
testBypass(t, false, pb, user, false)
}
@@ -9,10 +9,12 @@ import (
"slices"
"strings"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/timeutil"
"gitea.dev/models/db"
"gitea.dev/models/organization"
"gitea.dev/modules/glob"
"gitea.dev/modules/timeutil"
"xorm.io/builder"
)
// ProtectedTag struct
@@ -111,8 +113,7 @@ func GetProtectedTagByID(ctx context.Context, id int64) (*ProtectedTag, error) {
// GetProtectedTagByNamePattern gets protected tag by name_pattern
func GetProtectedTagByNamePattern(ctx context.Context, repoID int64, pattern string) (*ProtectedTag, error) {
tag := &ProtectedTag{NamePattern: pattern, RepoID: repoID}
has, err := db.GetEngine(ctx).Get(tag)
tag, has, err := db.Get[ProtectedTag](ctx, builder.Eq{"name_pattern": pattern, "repo_id": repoID})
if err != nil {
return nil, err
}
@@ -6,8 +6,8 @@ package git_test
import (
"testing"
git_model "code.gitea.io/gitea/models/git"
"code.gitea.io/gitea/models/unittest"
git_model "gitea.dev/models/git"
"gitea.dev/models/unittest"
"github.com/stretchr/testify/assert"
)