diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go
index 39d60380ff..9504bcf605 100644
--- a/services/pull/commit_status.go
+++ b/services/pull/commit_status.go
@@ -34,9 +34,9 @@ func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus,
 			}
 		}
 
-		for _, commitStatus := range commitStatuses {
+		for _, gp := range requiredContextsGlob {
 			var targetStatus structs.CommitStatusState
-			for _, gp := range requiredContextsGlob {
+			for _, commitStatus := range commitStatuses {
 				if gp.Match(commitStatus.Context) {
 					targetStatus = commitStatus.State
 					matchedCount++
@@ -44,7 +44,15 @@ func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus,
 				}
 			}
 
-			if targetStatus != "" && targetStatus.NoBetterThan(returnedStatus) {
+			// If required rule not match any action, then it is pending
+			if targetStatus == "" {
+				if structs.CommitStatusPending.NoBetterThan(returnedStatus) {
+					returnedStatus = structs.CommitStatusPending
+				}
+				break
+			}
+
+			if targetStatus.NoBetterThan(returnedStatus) {
 				returnedStatus = targetStatus
 			}
 		}
diff --git a/services/pull/commit_status_test.go b/services/pull/commit_status_test.go
new file mode 100644
index 0000000000..592acdd55c
--- /dev/null
+++ b/services/pull/commit_status_test.go
@@ -0,0 +1,65 @@
+// Copyright 2024 The Gitea Authors.
+// All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package pull
+
+import (
+	"testing"
+
+	git_model "code.gitea.io/gitea/models/git"
+	"code.gitea.io/gitea/modules/structs"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestMergeRequiredContextsCommitStatus(t *testing.T) {
+	testCases := [][]*git_model.CommitStatus{
+		{
+			{Context: "Build 1", State: structs.CommitStatusSuccess},
+			{Context: "Build 2", State: structs.CommitStatusSuccess},
+			{Context: "Build 3", State: structs.CommitStatusSuccess},
+		},
+		{
+			{Context: "Build 1", State: structs.CommitStatusSuccess},
+			{Context: "Build 2", State: structs.CommitStatusSuccess},
+			{Context: "Build 2t", State: structs.CommitStatusPending},
+		},
+		{
+			{Context: "Build 1", State: structs.CommitStatusSuccess},
+			{Context: "Build 2", State: structs.CommitStatusSuccess},
+			{Context: "Build 2t", State: structs.CommitStatusFailure},
+		},
+		{
+			{Context: "Build 1", State: structs.CommitStatusSuccess},
+			{Context: "Build 2", State: structs.CommitStatusSuccess},
+			{Context: "Build 2t", State: structs.CommitStatusSuccess},
+		},
+		{
+			{Context: "Build 1", State: structs.CommitStatusSuccess},
+			{Context: "Build 2", State: structs.CommitStatusSuccess},
+			{Context: "Build 2t", State: structs.CommitStatusSuccess},
+		},
+	}
+	testCasesRequiredContexts := [][]string{
+		{"Build*"},
+		{"Build*", "Build 2t*"},
+		{"Build*", "Build 2t*"},
+		{"Build*", "Build 2t*", "Build 3*"},
+		{"Build*", "Build *", "Build 2t*", "Build 1*"},
+	}
+
+	testCasesExpected := []structs.CommitStatusState{
+		structs.CommitStatusSuccess,
+		structs.CommitStatusPending,
+		structs.CommitStatusFailure,
+		structs.CommitStatusPending,
+		structs.CommitStatusSuccess,
+	}
+
+	for i, commitStatuses := range testCases {
+		if MergeRequiredContextsCommitStatus(commitStatuses, testCasesRequiredContexts[i]) != testCasesExpected[i] {
+			assert.Fail(t, "Test case failed", "Test case %d failed", i+1)
+		}
+	}
+}