mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Fix duplicate status check contexts (#30660)
Caused by #30076. There may be some duplicate status check contexts when setting status checks for a branch protection rule. The duplicate contexts should be removed. Before: <img src="https://github.com/go-gitea/gitea/assets/15528715/97f4de2d-4868-47a3-8a99-5a180f9ac0a3" width="600px" /> After: <img src="https://github.com/go-gitea/gitea/assets/15528715/ff7289c5-9793-4090-ba31-e8cb3c85f8a3" width="600px" />
This commit is contained in:
		| @@ -397,36 +397,16 @@ func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, co | |||||||
|  |  | ||||||
| // FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts | // FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts | ||||||
| func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, before time.Duration) ([]string, error) { | func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, before time.Duration) ([]string, error) { | ||||||
| 	type result struct { |  | ||||||
| 		Index int64 |  | ||||||
| 		SHA   string |  | ||||||
| 	} |  | ||||||
| 	getBase := func() *xorm.Session { |  | ||||||
| 		return db.GetEngine(ctx).Table(&CommitStatus{}).Where("repo_id = ?", repoID) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	start := timeutil.TimeStampNow().AddDuration(-before) | 	start := timeutil.TimeStampNow().AddDuration(-before) | ||||||
| 	results := make([]result, 0, 10) |  | ||||||
|  |  | ||||||
| 	sess := getBase().And("updated_unix >= ?", start). | 	var contexts []string | ||||||
| 		Select("max( `index` ) as `index`, sha"). | 	if err := db.GetEngine(ctx).Table("commit_status"). | ||||||
| 		GroupBy("context_hash, sha").OrderBy("max( `index` ) desc") | 		Where("repo_id = ?", repoID).And("updated_unix >= ?", start). | ||||||
|  | 		Cols("context").Distinct().Find(&contexts); err != nil { | ||||||
| 	err := sess.Find(&results) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	contexts := make([]string, 0, len(results)) | 	return contexts, nil | ||||||
| 	if len(results) == 0 { |  | ||||||
| 		return contexts, nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	conds := make([]builder.Cond, 0, len(results)) |  | ||||||
| 	for _, result := range results { |  | ||||||
| 		conds = append(conds, builder.Eq{"`index`": result.Index, "sha": result.SHA}) |  | ||||||
| 	} |  | ||||||
| 	return contexts, getBase().And(builder.Or(conds...)).Select("context").Find(&contexts) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // NewCommitStatusOptions holds options for creating a CommitStatus | // NewCommitStatusOptions holds options for creating a CommitStatus | ||||||
|   | |||||||
| @@ -5,11 +5,15 @@ package git_test | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	git_model "code.gitea.io/gitea/models/git" | 	git_model "code.gitea.io/gitea/models/git" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"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/gitrepo" | ||||||
| 	"code.gitea.io/gitea/modules/structs" | 	"code.gitea.io/gitea/modules/structs" | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| @@ -175,3 +179,55 @@ func Test_CalcCommitStatus(t *testing.T) { | |||||||
| 		assert.Equal(t, kase.expected, git_model.CalcCommitStatus(kase.statuses)) | 		assert.Equal(t, kase.expected, git_model.CalcCommitStatus(kase.statuses)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestFindRepoRecentCommitStatusContexts(t *testing.T) { | ||||||
|  | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
|  | 	repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) | ||||||
|  | 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
|  | 	gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo2) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	defer gitRepo.Close() | ||||||
|  |  | ||||||
|  | 	commit, err := gitRepo.GetBranchCommit(repo2.DefaultBranch) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  |  | ||||||
|  | 	defer func() { | ||||||
|  | 		_, err := db.DeleteByBean(db.DefaultContext, &git_model.CommitStatus{ | ||||||
|  | 			RepoID:    repo2.ID, | ||||||
|  | 			CreatorID: user2.ID, | ||||||
|  | 			SHA:       commit.ID.String(), | ||||||
|  | 		}) | ||||||
|  | 		assert.NoError(t, err) | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	err = git_model.NewCommitStatus(db.DefaultContext, git_model.NewCommitStatusOptions{ | ||||||
|  | 		Repo:    repo2, | ||||||
|  | 		Creator: user2, | ||||||
|  | 		SHA:     commit.ID, | ||||||
|  | 		CommitStatus: &git_model.CommitStatus{ | ||||||
|  | 			State:     structs.CommitStatusFailure, | ||||||
|  | 			TargetURL: "https://example.com/tests/", | ||||||
|  | 			Context:   "compliance/lint-backend", | ||||||
|  | 		}, | ||||||
|  | 	}) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  |  | ||||||
|  | 	err = git_model.NewCommitStatus(db.DefaultContext, git_model.NewCommitStatusOptions{ | ||||||
|  | 		Repo:    repo2, | ||||||
|  | 		Creator: user2, | ||||||
|  | 		SHA:     commit.ID, | ||||||
|  | 		CommitStatus: &git_model.CommitStatus{ | ||||||
|  | 			State:     structs.CommitStatusSuccess, | ||||||
|  | 			TargetURL: "https://example.com/tests/", | ||||||
|  | 			Context:   "compliance/lint-backend", | ||||||
|  | 		}, | ||||||
|  | 	}) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  |  | ||||||
|  | 	contexts, err := git_model.FindRepoRecentCommitStatusContexts(db.DefaultContext, repo2.ID, time.Hour) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	if assert.Len(t, contexts, 1) { | ||||||
|  | 		assert.Equal(t, "compliance/lint-backend", contexts[0]) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user