mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 20:36:07 +01:00 
			
		
		
		
	Support for status check pattern (#24633)
This PR is to allow users to specify status checks by patterns. Users can enter patterns in the "Status Check Pattern" `textarea` to match status checks and each line specifies a pattern. If "Status Check" is enabled, patterns cannot be empty and user must enter at least one pattern. Users will no longer be able to choose status checks from the table. But a __*`Matched`*__ mark will be added to the matched checks to help users enter patterns. Benefits: - Even if no status checks have been completed, users can specify necessary status checks in advance. - More flexible. Users can specify a series of status checks by one pattern. Before:  After:  --------- Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
		@@ -2190,8 +2190,13 @@ settings.protect_merge_whitelist_committers_desc = Allow only whitelisted users
 | 
				
			|||||||
settings.protect_merge_whitelist_users = Whitelisted users for merging:
 | 
					settings.protect_merge_whitelist_users = Whitelisted users for merging:
 | 
				
			||||||
settings.protect_merge_whitelist_teams = Whitelisted teams for merging:
 | 
					settings.protect_merge_whitelist_teams = Whitelisted teams for merging:
 | 
				
			||||||
settings.protect_check_status_contexts = Enable Status Check
 | 
					settings.protect_check_status_contexts = Enable Status Check
 | 
				
			||||||
settings.protect_check_status_contexts_desc = Require status checks to pass before merging. Choose which status checks must pass before branches can be merged into a branch that matches this rule. When enabled, commits must first be pushed to another branch, then merged or pushed directly to a branch that matches this rule after status checks have passed. If no contexts are selected, the last commit must be successful regardless of context.
 | 
					settings.protect_status_check_patterns = Status check patterns:
 | 
				
			||||||
 | 
					settings.protect_status_check_patterns_desc = Enter patterns to specify which status checks must pass before branches can be merged into a branch that matches this rule. Each line specifies a pattern. Patterns cannot be empty.
 | 
				
			||||||
 | 
					settings.protect_check_status_contexts_desc = Require status checks to pass before merging. When enabled, commits must first be pushed to another branch, then merged or pushed directly to a branch that matches this rule after status checks have passed. If no contexts are matched, the last commit must be successful regardless of context.
 | 
				
			||||||
settings.protect_check_status_contexts_list = Status checks found in the last week for this repository
 | 
					settings.protect_check_status_contexts_list = Status checks found in the last week for this repository
 | 
				
			||||||
 | 
					settings.protect_status_check_matched = Matched
 | 
				
			||||||
 | 
					settings.protect_invalid_status_check_pattern = Invalid status check pattern: "%s".
 | 
				
			||||||
 | 
					settings.protect_no_valid_status_check_patterns = No valid status check patterns.
 | 
				
			||||||
settings.protect_required_approvals = Required approvals:
 | 
					settings.protect_required_approvals = Required approvals:
 | 
				
			||||||
settings.protect_required_approvals_desc = Allow only to merge pull request with enough positive reviews.
 | 
					settings.protect_required_approvals_desc = Allow only to merge pull request with enough positive reviews.
 | 
				
			||||||
settings.protect_approvals_whitelist_enabled = Restrict approvals to whitelisted users or teams
 | 
					settings.protect_approvals_whitelist_enabled = Restrict approvals to whitelisted users or teams
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										197
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										197
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -35,6 +35,7 @@
 | 
				
			|||||||
        "license-checker-webpack-plugin": "0.2.1",
 | 
					        "license-checker-webpack-plugin": "0.2.1",
 | 
				
			||||||
        "mermaid": "10.1.0",
 | 
					        "mermaid": "10.1.0",
 | 
				
			||||||
        "mini-css-extract-plugin": "2.7.5",
 | 
					        "mini-css-extract-plugin": "2.7.5",
 | 
				
			||||||
 | 
					        "minimatch": "9.0.0",
 | 
				
			||||||
        "monaco-editor": "0.38.0",
 | 
					        "monaco-editor": "0.38.0",
 | 
				
			||||||
        "monaco-editor-webpack-plugin": "7.0.1",
 | 
					        "monaco-editor-webpack-plugin": "7.0.1",
 | 
				
			||||||
        "pretty-ms": "8.0.0",
 | 
					        "pretty-ms": "8.0.0",
 | 
				
			||||||
@@ -855,12 +856,34 @@
 | 
				
			|||||||
        "url": "https://github.com/sponsors/epoberezkin"
 | 
					        "url": "https://github.com/sponsors/epoberezkin"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
 | 
				
			||||||
 | 
					      "version": "1.1.11",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "balanced-match": "^1.0.0",
 | 
				
			||||||
 | 
					        "concat-map": "0.0.1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
 | 
					    "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
 | 
				
			||||||
      "version": "0.4.1",
 | 
					      "version": "0.4.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
 | 
					      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
 | 
				
			||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@eslint/eslintrc/node_modules/minimatch": {
 | 
				
			||||||
 | 
					      "version": "3.1.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "brace-expansion": "^1.1.7"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": "*"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@eslint/js": {
 | 
					    "node_modules/@eslint/js": {
 | 
				
			||||||
      "version": "8.40.0",
 | 
					      "version": "8.40.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
 | 
				
			||||||
@@ -907,6 +930,28 @@
 | 
				
			|||||||
        "node": ">=10.10.0"
 | 
					        "node": ">=10.10.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
 | 
				
			||||||
 | 
					      "version": "1.1.11",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "balanced-match": "^1.0.0",
 | 
				
			||||||
 | 
					        "concat-map": "0.0.1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
 | 
				
			||||||
 | 
					      "version": "3.1.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "brace-expansion": "^1.1.7"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": "*"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@humanwhocodes/module-importer": {
 | 
					    "node_modules/@humanwhocodes/module-importer": {
 | 
				
			||||||
      "version": "1.0.1",
 | 
					      "version": "1.0.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
 | 
				
			||||||
@@ -1480,6 +1525,28 @@
 | 
				
			|||||||
        "node": "^12.20 || >=14.13"
 | 
					        "node": "^12.20 || >=14.13"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@stoplight/spectral-core/node_modules/brace-expansion": {
 | 
				
			||||||
 | 
					      "version": "1.1.11",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "balanced-match": "^1.0.0",
 | 
				
			||||||
 | 
					        "concat-map": "0.0.1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@stoplight/spectral-core/node_modules/minimatch": {
 | 
				
			||||||
 | 
					      "version": "3.1.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "brace-expansion": "^1.1.7"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": "*"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@stoplight/spectral-formats": {
 | 
					    "node_modules/@stoplight/spectral-formats": {
 | 
				
			||||||
      "version": "1.5.0",
 | 
					      "version": "1.5.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.5.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.5.0.tgz",
 | 
				
			||||||
@@ -2668,12 +2735,11 @@
 | 
				
			|||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/brace-expansion": {
 | 
					    "node_modules/brace-expansion": {
 | 
				
			||||||
      "version": "1.1.11",
 | 
					      "version": "2.0.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
 | 
					      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "balanced-match": "^1.0.0",
 | 
					        "balanced-match": "^1.0.0"
 | 
				
			||||||
        "concat-map": "0.0.1"
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/braces": {
 | 
					    "node_modules/braces": {
 | 
				
			||||||
@@ -4574,6 +4640,16 @@
 | 
				
			|||||||
        "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
 | 
					        "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/eslint-plugin-import/node_modules/brace-expansion": {
 | 
				
			||||||
 | 
					      "version": "1.1.11",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "balanced-match": "^1.0.0",
 | 
				
			||||||
 | 
					        "concat-map": "0.0.1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/eslint-plugin-import/node_modules/debug": {
 | 
					    "node_modules/eslint-plugin-import/node_modules/debug": {
 | 
				
			||||||
      "version": "3.2.7",
 | 
					      "version": "3.2.7",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
 | 
				
			||||||
@@ -4595,6 +4671,18 @@
 | 
				
			|||||||
        "node": ">=0.10.0"
 | 
					        "node": ">=0.10.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/eslint-plugin-import/node_modules/minimatch": {
 | 
				
			||||||
 | 
					      "version": "3.1.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "brace-expansion": "^1.1.7"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": "*"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/eslint-plugin-import/node_modules/semver": {
 | 
					    "node_modules/eslint-plugin-import/node_modules/semver": {
 | 
				
			||||||
      "version": "6.3.0",
 | 
					      "version": "6.3.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
 | 
				
			||||||
@@ -4767,12 +4855,34 @@
 | 
				
			|||||||
        "url": "https://github.com/sponsors/epoberezkin"
 | 
					        "url": "https://github.com/sponsors/epoberezkin"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/eslint/node_modules/brace-expansion": {
 | 
				
			||||||
 | 
					      "version": "1.1.11",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "balanced-match": "^1.0.0",
 | 
				
			||||||
 | 
					        "concat-map": "0.0.1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/eslint/node_modules/json-schema-traverse": {
 | 
					    "node_modules/eslint/node_modules/json-schema-traverse": {
 | 
				
			||||||
      "version": "0.4.1",
 | 
					      "version": "0.4.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
 | 
					      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
 | 
				
			||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/eslint/node_modules/minimatch": {
 | 
				
			||||||
 | 
					      "version": "3.1.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
 | 
				
			||||||
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "brace-expansion": "^1.1.7"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": "*"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/espree": {
 | 
					    "node_modules/espree": {
 | 
				
			||||||
      "version": "9.5.2",
 | 
					      "version": "9.5.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
 | 
				
			||||||
@@ -5273,6 +5383,26 @@
 | 
				
			|||||||
      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
 | 
					      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/glob/node_modules/brace-expansion": {
 | 
				
			||||||
 | 
					      "version": "1.1.11",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "balanced-match": "^1.0.0",
 | 
				
			||||||
 | 
					        "concat-map": "0.0.1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/glob/node_modules/minimatch": {
 | 
				
			||||||
 | 
					      "version": "3.1.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "brace-expansion": "^1.1.7"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": "*"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/global-modules": {
 | 
					    "node_modules/global-modules": {
 | 
				
			||||||
      "version": "2.0.0",
 | 
					      "version": "2.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
 | 
				
			||||||
@@ -6396,6 +6526,26 @@
 | 
				
			|||||||
        "webpack": "^4.4.0 || ^5.4.0"
 | 
					        "webpack": "^4.4.0 || ^5.4.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/license-checker-webpack-plugin/node_modules/brace-expansion": {
 | 
				
			||||||
 | 
					      "version": "1.1.11",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "balanced-match": "^1.0.0",
 | 
				
			||||||
 | 
					        "concat-map": "0.0.1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/license-checker-webpack-plugin/node_modules/minimatch": {
 | 
				
			||||||
 | 
					      "version": "3.1.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "brace-expansion": "^1.1.7"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": "*"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/license-checker-webpack-plugin/node_modules/semver": {
 | 
					    "node_modules/license-checker-webpack-plugin/node_modules/semver": {
 | 
				
			||||||
      "version": "6.3.0",
 | 
					      "version": "6.3.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
 | 
				
			||||||
@@ -6645,15 +6795,6 @@
 | 
				
			|||||||
        "node": ">=14"
 | 
					        "node": ">=14"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/markdownlint-cli/node_modules/brace-expansion": {
 | 
					 | 
				
			||||||
      "version": "2.0.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "balanced-match": "^1.0.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/markdownlint-cli/node_modules/commander": {
 | 
					    "node_modules/markdownlint-cli/node_modules/commander": {
 | 
				
			||||||
      "version": "10.0.1",
 | 
					      "version": "10.0.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
 | 
				
			||||||
@@ -6691,21 +6832,6 @@
 | 
				
			|||||||
      "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
 | 
					      "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
 | 
				
			||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/markdownlint-cli/node_modules/minimatch": {
 | 
					 | 
				
			||||||
      "version": "9.0.0",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "brace-expansion": "^2.0.1"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=16 || 14 >=14.17"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "url": "https://github.com/sponsors/isaacs"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/markdownlint-micromark": {
 | 
					    "node_modules/markdownlint-micromark": {
 | 
				
			||||||
      "version": "0.1.2",
 | 
					      "version": "0.1.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.2.tgz",
 | 
				
			||||||
@@ -6939,14 +7065,17 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/minimatch": {
 | 
					    "node_modules/minimatch": {
 | 
				
			||||||
      "version": "3.1.2",
 | 
					      "version": "9.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
 | 
					      "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "brace-expansion": "^1.1.7"
 | 
					        "brace-expansion": "^2.0.1"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": "*"
 | 
					        "node": ">=16 || 14 >=14.17"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/sponsors/isaacs"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/minimist": {
 | 
					    "node_modules/minimist": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,6 +35,7 @@
 | 
				
			|||||||
    "license-checker-webpack-plugin": "0.2.1",
 | 
					    "license-checker-webpack-plugin": "0.2.1",
 | 
				
			||||||
    "mermaid": "10.1.0",
 | 
					    "mermaid": "10.1.0",
 | 
				
			||||||
    "mini-css-extract-plugin": "2.7.5",
 | 
					    "mini-css-extract-plugin": "2.7.5",
 | 
				
			||||||
 | 
					    "minimatch": "9.0.0",
 | 
				
			||||||
    "monaco-editor": "0.38.0",
 | 
					    "monaco-editor": "0.38.0",
 | 
				
			||||||
    "monaco-editor-webpack-plugin": "7.0.1",
 | 
					    "monaco-editor-webpack-plugin": "7.0.1",
 | 
				
			||||||
    "pretty-ms": "8.0.0",
 | 
					    "pretty-ms": "8.0.0",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,6 +45,8 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/services/gitdiff"
 | 
						"code.gitea.io/gitea/services/gitdiff"
 | 
				
			||||||
	pull_service "code.gitea.io/gitea/services/pull"
 | 
						pull_service "code.gitea.io/gitea/services/pull"
 | 
				
			||||||
	repo_service "code.gitea.io/gitea/services/repository"
 | 
						repo_service "code.gitea.io/gitea/services/repository"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/gobwas/glob"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -575,7 +577,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
 | 
				
			|||||||
	if pb != nil && pb.EnableStatusCheck {
 | 
						if pb != nil && pb.EnableStatusCheck {
 | 
				
			||||||
		ctx.Data["is_context_required"] = func(context string) bool {
 | 
							ctx.Data["is_context_required"] = func(context string) bool {
 | 
				
			||||||
			for _, c := range pb.StatusCheckContexts {
 | 
								for _, c := range pb.StatusCheckContexts {
 | 
				
			||||||
				if c == context {
 | 
									if gp, err := glob.Compile(c); err == nil && gp.Match(context) {
 | 
				
			||||||
					return true
 | 
										return true
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ package repo
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,6 +24,8 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/services/forms"
 | 
						"code.gitea.io/gitea/services/forms"
 | 
				
			||||||
	pull_service "code.gitea.io/gitea/services/pull"
 | 
						pull_service "code.gitea.io/gitea/services/pull"
 | 
				
			||||||
	"code.gitea.io/gitea/services/repository"
 | 
						"code.gitea.io/gitea/services/repository"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/gobwas/glob"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -115,21 +118,10 @@ func SettingsProtectedBranch(c *context.Context) {
 | 
				
			|||||||
	c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(rule.WhitelistUserIDs), ",")
 | 
						c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(rule.WhitelistUserIDs), ",")
 | 
				
			||||||
	c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.MergeWhitelistUserIDs), ",")
 | 
						c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.MergeWhitelistUserIDs), ",")
 | 
				
			||||||
	c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.ApprovalsWhitelistUserIDs), ",")
 | 
						c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.ApprovalsWhitelistUserIDs), ",")
 | 
				
			||||||
 | 
						c.Data["status_check_contexts"] = strings.Join(rule.StatusCheckContexts, "\n")
 | 
				
			||||||
	contexts, _ := git_model.FindRepoRecentCommitStatusContexts(c, c.Repo.Repository.ID, 7*24*time.Hour) // Find last week status check contexts
 | 
						contexts, _ := git_model.FindRepoRecentCommitStatusContexts(c, c.Repo.Repository.ID, 7*24*time.Hour) // Find last week status check contexts
 | 
				
			||||||
	for _, ctx := range rule.StatusCheckContexts {
 | 
						c.Data["recent_status_checks"] = contexts
 | 
				
			||||||
		var found bool
 | 
					 | 
				
			||||||
		for i := range contexts {
 | 
					 | 
				
			||||||
			if contexts[i] == ctx {
 | 
					 | 
				
			||||||
				found = true
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if !found {
 | 
					 | 
				
			||||||
			contexts = append(contexts, ctx)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.Data["branch_status_check_contexts"] = contexts
 | 
					 | 
				
			||||||
	if c.Repo.Owner.IsOrganization() {
 | 
						if c.Repo.Owner.IsOrganization() {
 | 
				
			||||||
		teams, err := organization.OrgFromUser(c.Repo.Owner).TeamsWithAccessToRepo(c.Repo.Repository.ID, perm.AccessModeRead)
 | 
							teams, err := organization.OrgFromUser(c.Repo.Owner).TeamsWithAccessToRepo(c.Repo.Repository.ID, perm.AccessModeRead)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -237,7 +229,27 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	protectBranch.EnableStatusCheck = f.EnableStatusCheck
 | 
						protectBranch.EnableStatusCheck = f.EnableStatusCheck
 | 
				
			||||||
	if f.EnableStatusCheck {
 | 
						if f.EnableStatusCheck {
 | 
				
			||||||
		protectBranch.StatusCheckContexts = f.StatusCheckContexts
 | 
							patterns := strings.Split(strings.ReplaceAll(f.StatusCheckContexts, "\r", "\n"), "\n")
 | 
				
			||||||
 | 
							validPatterns := make([]string, 0, len(patterns))
 | 
				
			||||||
 | 
							for _, pattern := range patterns {
 | 
				
			||||||
 | 
								trimmed := strings.TrimSpace(pattern)
 | 
				
			||||||
 | 
								if trimmed == "" {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if _, err := glob.Compile(trimmed); err != nil {
 | 
				
			||||||
 | 
									ctx.Flash.Error(ctx.Tr("repo.settings.protect_invalid_status_check_pattern", pattern))
 | 
				
			||||||
 | 
									ctx.Redirect(fmt.Sprintf("%s/settings/branches/edit?rule_name=%s", ctx.Repo.RepoLink, url.QueryEscape(protectBranch.RuleName)))
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								validPatterns = append(validPatterns, trimmed)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(validPatterns) == 0 {
 | 
				
			||||||
 | 
								// if status check is enabled, patterns slice is not allowed to be empty
 | 
				
			||||||
 | 
								ctx.Flash.Error(ctx.Tr("repo.settings.protect_no_valid_status_check_patterns"))
 | 
				
			||||||
 | 
								ctx.Redirect(fmt.Sprintf("%s/settings/branches/edit?rule_name=%s", ctx.Repo.RepoLink, url.QueryEscape(protectBranch.RuleName)))
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							protectBranch.StatusCheckContexts = validPatterns
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		protectBranch.StatusCheckContexts = nil
 | 
							protectBranch.StatusCheckContexts = nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -199,7 +199,7 @@ type ProtectBranchForm struct {
 | 
				
			|||||||
	MergeWhitelistUsers           string
 | 
						MergeWhitelistUsers           string
 | 
				
			||||||
	MergeWhitelistTeams           string
 | 
						MergeWhitelistTeams           string
 | 
				
			||||||
	EnableStatusCheck             bool
 | 
						EnableStatusCheck             bool
 | 
				
			||||||
	StatusCheckContexts           []string
 | 
						StatusCheckContexts           string
 | 
				
			||||||
	RequiredApprovals             int64
 | 
						RequiredApprovals             int64
 | 
				
			||||||
	EnableApprovalsWhitelist      bool
 | 
						EnableApprovalsWhitelist      bool
 | 
				
			||||||
	ApprovalsWhitelistUsers       string
 | 
						ApprovalsWhitelistUsers       string
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,14 +11,46 @@ import (
 | 
				
			|||||||
	git_model "code.gitea.io/gitea/models/git"
 | 
						git_model "code.gitea.io/gitea/models/git"
 | 
				
			||||||
	issues_model "code.gitea.io/gitea/models/issues"
 | 
						issues_model "code.gitea.io/gitea/models/issues"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/git"
 | 
						"code.gitea.io/gitea/modules/git"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/structs"
 | 
						"code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/gobwas/glob"
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MergeRequiredContextsCommitStatus returns a commit status state for given required contexts
 | 
					// MergeRequiredContextsCommitStatus returns a commit status state for given required contexts
 | 
				
			||||||
func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus, requiredContexts []string) structs.CommitStatusState {
 | 
					func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus, requiredContexts []string) structs.CommitStatusState {
 | 
				
			||||||
	if len(requiredContexts) == 0 {
 | 
						// matchedCount is the number of `CommitStatus.Context` that match any context of `requiredContexts`
 | 
				
			||||||
 | 
						matchedCount := 0
 | 
				
			||||||
 | 
						returnedStatus := structs.CommitStatusSuccess
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(requiredContexts) > 0 {
 | 
				
			||||||
 | 
							requiredContextsGlob := make(map[string]glob.Glob, len(requiredContexts))
 | 
				
			||||||
 | 
							for _, ctx := range requiredContexts {
 | 
				
			||||||
 | 
								if gp, err := glob.Compile(ctx); err != nil {
 | 
				
			||||||
 | 
									log.Error("glob.Compile %s failed. Error: %v", ctx, err)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									requiredContextsGlob[ctx] = gp
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, commitStatus := range commitStatuses {
 | 
				
			||||||
 | 
								var targetStatus structs.CommitStatusState
 | 
				
			||||||
 | 
								for _, gp := range requiredContextsGlob {
 | 
				
			||||||
 | 
									if gp.Match(commitStatus.Context) {
 | 
				
			||||||
 | 
										targetStatus = commitStatus.State
 | 
				
			||||||
 | 
										matchedCount++
 | 
				
			||||||
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if targetStatus != "" && targetStatus.NoBetterThan(returnedStatus) {
 | 
				
			||||||
 | 
									returnedStatus = targetStatus
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if matchedCount == 0 {
 | 
				
			||||||
		status := git_model.CalcCommitStatus(commitStatuses)
 | 
							status := git_model.CalcCommitStatus(commitStatuses)
 | 
				
			||||||
		if status != nil {
 | 
							if status != nil {
 | 
				
			||||||
			return status.State
 | 
								return status.State
 | 
				
			||||||
@@ -26,28 +58,6 @@ func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus,
 | 
				
			|||||||
		return structs.CommitStatusSuccess
 | 
							return structs.CommitStatusSuccess
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	returnedStatus := structs.CommitStatusSuccess
 | 
					 | 
				
			||||||
	for _, ctx := range requiredContexts {
 | 
					 | 
				
			||||||
		var targetStatus structs.CommitStatusState
 | 
					 | 
				
			||||||
		for _, commitStatus := range commitStatuses {
 | 
					 | 
				
			||||||
			if commitStatus.Context == ctx {
 | 
					 | 
				
			||||||
				targetStatus = commitStatus.State
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if targetStatus == "" {
 | 
					 | 
				
			||||||
			targetStatus = structs.CommitStatusPending
 | 
					 | 
				
			||||||
			commitStatuses = append(commitStatuses, &git_model.CommitStatus{
 | 
					 | 
				
			||||||
				State:       targetStatus,
 | 
					 | 
				
			||||||
				Context:     ctx,
 | 
					 | 
				
			||||||
				Description: "Pending",
 | 
					 | 
				
			||||||
			})
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if targetStatus.NoBetterThan(returnedStatus) {
 | 
					 | 
				
			||||||
			returnedStatus = targetStatus
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return returnedStatus
 | 
						return returnedStatus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -157,6 +157,9 @@
 | 
				
			|||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					<div id="statuscheck_contexts_box" class="checkbox-sub-item field {{if not .Rule.EnableStatusCheck}}disabled{{end}}">
 | 
										<div id="statuscheck_contexts_box" class="checkbox-sub-item field {{if not .Rule.EnableStatusCheck}}disabled{{end}}">
 | 
				
			||||||
 | 
											<label>{{.locale.Tr "repo.settings.protect_status_check_patterns"}}</label>
 | 
				
			||||||
 | 
											<textarea id="status_check_contexts" name="status_check_contexts" rows="3">{{.status_check_contexts}}</textarea>
 | 
				
			||||||
 | 
											<p class="help">{{.locale.Tr "repo.settings.protect_status_check_patterns_desc"}}</p>
 | 
				
			||||||
						<table class="ui celled table">
 | 
											<table class="ui celled table">
 | 
				
			||||||
							<thead>
 | 
												<thead>
 | 
				
			||||||
								<tr>
 | 
													<tr>
 | 
				
			||||||
@@ -164,13 +167,11 @@
 | 
				
			|||||||
								</tr>
 | 
													</tr>
 | 
				
			||||||
							</thead>
 | 
												</thead>
 | 
				
			||||||
							<tbody>
 | 
												<tbody>
 | 
				
			||||||
							{{range $.branch_status_check_contexts}}
 | 
												{{range $.recent_status_checks}}
 | 
				
			||||||
								<tr>
 | 
													<tr>
 | 
				
			||||||
									<td>
 | 
														<td>
 | 
				
			||||||
										<span class="ui checkbox">
 | 
															<span>{{.}}</span>
 | 
				
			||||||
											<label>{{.}}</label>
 | 
															<span class="status-check-matched-mark gt-hidden" data-status-check="{{.}}">{{$.locale.Tr "repo.settings.protect_status_check_matched"}}</span>
 | 
				
			||||||
											<input name="status_check_contexts" value="{{.}}" type="checkbox" {{if SliceUtils.Contains $.Rule.StatusCheckContexts .}}checked{{end}}>
 | 
					 | 
				
			||||||
										</span>
 | 
					 | 
				
			||||||
									</td>
 | 
														</td>
 | 
				
			||||||
								</tr>
 | 
													</tr>
 | 
				
			||||||
							{{else}}
 | 
												{{else}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1990,6 +1990,11 @@
 | 
				
			|||||||
  padding-left: 26px;
 | 
					  padding-left: 26px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.repository.settings.branches .branch-protection .status-check-matched-mark {
 | 
				
			||||||
 | 
					  font-weight: var(--font-weight-bold);
 | 
				
			||||||
 | 
					  font-style: italic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.repository.settings.webhook .events .column {
 | 
					.repository.settings.webhook .events .column {
 | 
				
			||||||
  padding-bottom: 0;
 | 
					  padding-bottom: 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
import $ from 'jquery';
 | 
					import $ from 'jquery';
 | 
				
			||||||
 | 
					import {minimatch} from 'minimatch';
 | 
				
			||||||
import {createMonaco} from './codeeditor.js';
 | 
					import {createMonaco} from './codeeditor.js';
 | 
				
			||||||
 | 
					import {onInputDebounce, toggleElem} from '../utils/dom.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const {appSubUrl, csrfToken} = window.config;
 | 
					const {appSubUrl, csrfToken} = window.config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,4 +83,26 @@ export function initRepoSettingBranches() {
 | 
				
			|||||||
    const $target = $($(this).attr('data-target'));
 | 
					    const $target = $($(this).attr('data-target'));
 | 
				
			||||||
    if (this.checked) $target.addClass('disabled'); // only disable, do not auto enable
 | 
					    if (this.checked) $target.addClass('disabled'); // only disable, do not auto enable
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // show the `Matched` mark for the status checks that match the pattern
 | 
				
			||||||
 | 
					  const markMatchedStatusChecks = () => {
 | 
				
			||||||
 | 
					    const patterns = (document.getElementById('status_check_contexts').value || '').split(/[\r\n]+/);
 | 
				
			||||||
 | 
					    const validPatterns = patterns.map((item) => item.trim()).filter(Boolean);
 | 
				
			||||||
 | 
					    const marks = document.getElementsByClassName('status-check-matched-mark');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (const el of marks) {
 | 
				
			||||||
 | 
					      let matched = false;
 | 
				
			||||||
 | 
					      const statusCheck = el.getAttribute('data-status-check');
 | 
				
			||||||
 | 
					      for (const pattern of validPatterns) {
 | 
				
			||||||
 | 
					        if (minimatch(statusCheck, pattern)) {
 | 
				
			||||||
 | 
					          matched = true;
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      toggleElem(el, matched);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  markMatchedStatusChecks();
 | 
				
			||||||
 | 
					  document.getElementById('status_check_contexts').addEventListener('input', onInputDebounce(markMatchedStatusChecks));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user