Publish curated ITWorx_MCP_Hub source from 6c7434368ce2a594005983c5a6601a31a639e7f1
This commit is contained in:
1 parent
77946d62c4
commit
6d40ab975c
86 files changed
+6784
-1478
No files matched your search
+99
-91
@@ -16,7 +16,7 @@ from threading import Lock
|
||||
from typing import Any, Literal
|
||||
from urllib.parse import quote, unquote, urlparse
|
||||
|
||||
import yaml
|
||||
import yaml # type: ignore[import-untyped]
|
||||
|
||||
from packages.connector_kit import (
|
||||
ConnectorContext,
|
||||
@@ -120,7 +120,7 @@ _PROJECTBRAIN_VALIDATION_CONCURRENCY = {
|
||||
}
|
||||
|
||||
|
||||
class _UniqueWorkflowLoader(yaml.BaseLoader):
|
||||
class _UniqueWorkflowLoader(yaml.BaseLoader): # type: ignore[misc]
|
||||
"""Parse workflow YAML without YAML 1.1's special treatment of the `on` key."""
|
||||
|
||||
|
||||
@@ -205,21 +205,17 @@ def _projectbrain_managed_validation_is_strong(workflow_content: str) -> bool:
|
||||
return False
|
||||
|
||||
triggers = _workflow_mapping(document.get("on"))
|
||||
if (
|
||||
triggers is None
|
||||
or set(triggers) != {"push", "pull_request", "workflow_dispatch"}
|
||||
):
|
||||
if triggers is None or set(triggers) != {"push", "pull_request", "workflow_dispatch"}:
|
||||
return False
|
||||
dispatch = _workflow_mapping(triggers.get("workflow_dispatch"))
|
||||
dispatch_inputs = _workflow_mapping(dispatch.get("inputs")) if dispatch is not None else None
|
||||
if dispatch is None or set(dispatch) != {"inputs"}:
|
||||
return False
|
||||
dispatch_inputs = _workflow_mapping(dispatch.get("inputs"))
|
||||
profile_input = (
|
||||
_workflow_mapping(dispatch_inputs.get("profile"))
|
||||
if dispatch_inputs is not None
|
||||
else None
|
||||
_workflow_mapping(dispatch_inputs.get("profile")) if dispatch_inputs is not None else None
|
||||
)
|
||||
if (
|
||||
dispatch_inputs is None
|
||||
or set(dispatch) != {"inputs"}
|
||||
or set(dispatch_inputs) != {"profile"}
|
||||
or profile_input is None
|
||||
or set(profile_input) != {"description", "required", "default", "type", "options"}
|
||||
@@ -231,11 +227,7 @@ def _projectbrain_managed_validation_is_strong(workflow_content: str) -> bool:
|
||||
):
|
||||
return False
|
||||
push = _workflow_mapping(triggers.get("push"))
|
||||
if (
|
||||
push is None
|
||||
or set(push) != {"branches"}
|
||||
or push.get("branches") != ["main"]
|
||||
):
|
||||
if push is None or set(push) != {"branches"} or push.get("branches") != ["main"]:
|
||||
return False
|
||||
pull_request = triggers.get("pull_request")
|
||||
if pull_request not in (None, ""):
|
||||
@@ -1028,9 +1020,7 @@ class GiteaConnector:
|
||||
if isinstance(existing_contexts, list)
|
||||
else set()
|
||||
)
|
||||
desired["status_check_contexts"] = sorted(
|
||||
set(required_contexts).union(preserved_contexts)
|
||||
)
|
||||
desired["status_check_contexts"] = sorted(set(required_contexts).union(preserved_contexts))
|
||||
current_projection = _branch_protection_projection(current)
|
||||
protection_diff = {
|
||||
key: {
|
||||
@@ -1061,12 +1051,9 @@ class GiteaConnector:
|
||||
if workflow_content is not None
|
||||
else None
|
||||
)
|
||||
workflow_profile = _managed_validation_profile(
|
||||
repository.qualified_name, workflow_content
|
||||
)
|
||||
workflow_profile = _managed_validation_profile(repository.qualified_name, workflow_content)
|
||||
is_projectbrain = (
|
||||
repository.qualified_name.casefold()
|
||||
== _PROJECTBRAIN_MANAGED_VALIDATION_REPOSITORY
|
||||
repository.qualified_name.casefold() == _PROJECTBRAIN_MANAGED_VALIDATION_REPOSITORY
|
||||
)
|
||||
if is_projectbrain and workflow_profile is None:
|
||||
blockers.append("managed-validation-projectbrain-profile-invalid")
|
||||
@@ -1083,9 +1070,7 @@ class GiteaConnector:
|
||||
else "update"
|
||||
)
|
||||
desired_workflow_digest = (
|
||||
workflow_digest
|
||||
if workflow_profile == "projectbrain"
|
||||
else MANAGED_VALIDATION_DIGEST
|
||||
workflow_digest if workflow_profile == "projectbrain" else MANAGED_VALIDATION_DIGEST
|
||||
)
|
||||
if is_projectbrain and current_projection is not None:
|
||||
if any(
|
||||
@@ -1250,11 +1235,7 @@ class GiteaConnector:
|
||||
if apply_scope not in {"all", "protection_only"}:
|
||||
raise GiteaError("GITEA_INPUT_INVALID", "governance apply scope is not allowlisted")
|
||||
plan = self._governance_plan_data(context, repository_ref)
|
||||
expected_hash = (
|
||||
plan["planHash"]
|
||||
if apply_scope == "all"
|
||||
else plan["protectionOnlyPlanHash"]
|
||||
)
|
||||
expected_hash = plan["planHash"] if apply_scope == "all" else plan["protectionOnlyPlanHash"]
|
||||
if (
|
||||
not isinstance(expected_hash, str)
|
||||
or not re.fullmatch(r"[0-9a-f]{64}", expected_plan_hash)
|
||||
@@ -1267,9 +1248,8 @@ class GiteaConnector:
|
||||
|
||||
if apply_scope == "protection_only":
|
||||
allowed_blockers = {"managed-validation-projectbrain-profile-invalid"}
|
||||
if (
|
||||
not plan["_protectionOnlyAvailable"]
|
||||
or any(blocker not in allowed_blockers for blocker in plan["blockers"])
|
||||
if not plan["_protectionOnlyAvailable"] or any(
|
||||
blocker not in allowed_blockers for blocker in plan["blockers"]
|
||||
):
|
||||
raise GiteaError(
|
||||
"GITEA_GOVERNANCE_BLOCKED",
|
||||
@@ -1311,16 +1291,17 @@ class GiteaConnector:
|
||||
actual_effective_protection = _branch_protection_effective_projection(
|
||||
verified_plan["_currentProtection"]
|
||||
)
|
||||
actual_contexts = set(
|
||||
verified_protection.get("status_check_contexts") or []
|
||||
) if verified_protection is not None else set()
|
||||
actual_contexts = (
|
||||
set(verified_protection.get("status_check_contexts") or [])
|
||||
if verified_protection is not None
|
||||
else set()
|
||||
)
|
||||
if (
|
||||
verified_protection is None
|
||||
or verified_protection.get("enable_status_check") is not True
|
||||
or actual_contexts != set(expected_contexts)
|
||||
or actual_effective_protection != expected_effective_protection
|
||||
or verified_plan["workflow"]["currentDigest"]
|
||||
!= plan["workflow"]["currentDigest"]
|
||||
or verified_plan["workflow"]["currentDigest"] != plan["workflow"]["currentDigest"]
|
||||
):
|
||||
raise GiteaError(
|
||||
"GITEA_GOVERNANCE_VERIFY_FAILED",
|
||||
@@ -1379,9 +1360,7 @@ class GiteaConnector:
|
||||
writer.create_branch_protection(repository, desired)
|
||||
elif protection_action == "update":
|
||||
if plan["workflow"]["profile"] == "projectbrain":
|
||||
edit_payload = {
|
||||
"status_check_contexts": desired["status_check_contexts"]
|
||||
}
|
||||
edit_payload = {"status_check_contexts": desired["status_check_contexts"]}
|
||||
else:
|
||||
edit_payload = {
|
||||
key: value
|
||||
@@ -1420,28 +1399,22 @@ class GiteaConnector:
|
||||
verified_plan = self._governance_plan_data(context, repository_ref)
|
||||
is_projectbrain_profile = plan["workflow"]["profile"] == "projectbrain"
|
||||
verified_contexts = set(
|
||||
(verified_plan["branchProtection"]["current"] or {}).get(
|
||||
"status_check_contexts"
|
||||
)
|
||||
or []
|
||||
(verified_plan["branchProtection"]["current"] or {}).get("status_check_contexts") or []
|
||||
)
|
||||
expected_contexts = set(
|
||||
verified_expected_contexts = set(
|
||||
plan["branchProtection"]["desired"].get("status_check_contexts") or []
|
||||
)
|
||||
projectbrain_protection_changed = is_projectbrain_profile and (
|
||||
verified_contexts != expected_contexts
|
||||
verified_contexts != verified_expected_contexts
|
||||
or (
|
||||
plan["_currentProtection"] is not None
|
||||
and _branch_protection_effective_projection(
|
||||
verified_plan["_currentProtection"]
|
||||
)
|
||||
and _branch_protection_effective_projection(verified_plan["_currentProtection"])
|
||||
!= _branch_protection_effective_projection(plan["_currentProtection"])
|
||||
)
|
||||
)
|
||||
projectbrain_workflow_changed = (
|
||||
is_projectbrain_profile
|
||||
and verified_plan["workflow"]["currentDigest"]
|
||||
!= plan["workflow"]["currentDigest"]
|
||||
and verified_plan["workflow"]["currentDigest"] != plan["workflow"]["currentDigest"]
|
||||
)
|
||||
if (
|
||||
not verified_plan["compliant"]
|
||||
@@ -2245,7 +2218,9 @@ class GiteaConnector:
|
||||
next_actions.append("fix-validation")
|
||||
if pull is not None and not ready_to_merge:
|
||||
if merge_eligibility["reason"] in {
|
||||
"GITEA_PR_CHECK_MISSING", "GITEA_PR_CHECK_PENDING", "GITEA_PR_CHECK_FAILED",
|
||||
"GITEA_PR_CHECK_MISSING",
|
||||
"GITEA_PR_CHECK_PENDING",
|
||||
"GITEA_PR_CHECK_FAILED",
|
||||
"GITEA_PR_VALIDATION_REQUIRED",
|
||||
}:
|
||||
next_actions.append("ensure-pr-validation")
|
||||
@@ -2276,9 +2251,8 @@ class GiteaConnector:
|
||||
),
|
||||
"validationState": (
|
||||
"pr_check_missing"
|
||||
if merge_eligibility["reason"] in {
|
||||
"GITEA_PR_CHECK_MISSING", "GITEA_PR_VALIDATION_REQUIRED"
|
||||
}
|
||||
if merge_eligibility["reason"]
|
||||
in {"GITEA_PR_CHECK_MISSING", "GITEA_PR_VALIDATION_REQUIRED"}
|
||||
else "pr_check_pending"
|
||||
if merge_eligibility["reason"] == "GITEA_PR_CHECK_PENDING"
|
||||
else "pr_check_failed"
|
||||
@@ -3924,7 +3898,10 @@ class GiteaConnector:
|
||||
|
||||
@governed_tool("gitea.pullrequest.validation.ensure")
|
||||
def pull_request_validation_ensure(
|
||||
self, context: ConnectorContext, repository_ref: str, number: int,
|
||||
self,
|
||||
context: ConnectorContext,
|
||||
repository_ref: str,
|
||||
number: int,
|
||||
expected_head_sha: str,
|
||||
) -> dict[str, Any]:
|
||||
"""Reuse or retrigger a real full pull_request run for the exact PR head."""
|
||||
@@ -3942,10 +3919,8 @@ class GiteaConnector:
|
||||
if str(base.get("ref", "")) != default_branch:
|
||||
raise GiteaError("GITEA_TARGET_INVALID", "PR does not target the default branch")
|
||||
protection = self.client.branch_protection(repository, str(base.get("ref", "")))
|
||||
if (
|
||||
not protection.get("enable_status_check")
|
||||
or MANAGED_VALIDATION_CONTEXT not in
|
||||
(protection.get("status_check_contexts") or [])
|
||||
if not protection.get("enable_status_check") or MANAGED_VALIDATION_CONTEXT not in (
|
||||
protection.get("status_check_contexts") or []
|
||||
):
|
||||
raise GiteaError("GITEA_PROTECTION_DRIFT", "canonical PR check is not required")
|
||||
|
||||
@@ -3958,7 +3933,8 @@ class GiteaConnector:
|
||||
break
|
||||
return sorted(
|
||||
(
|
||||
self._action_run_projection(item) for item in runs
|
||||
self._action_run_projection(item)
|
||||
for item in runs
|
||||
if str(item.get("event", "")) == "pull_request"
|
||||
and str(item.get("head_sha", "")) == expected_head_sha
|
||||
and (
|
||||
@@ -3971,7 +3947,8 @@ class GiteaConnector:
|
||||
)
|
||||
)
|
||||
),
|
||||
key=lambda item: int(item.get("id", 0)), reverse=True,
|
||||
key=lambda item: int(item.get("id", 0)),
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
runs = exact_runs()
|
||||
@@ -3983,9 +3960,11 @@ class GiteaConnector:
|
||||
for run in runs:
|
||||
run_id = int(run["id"])
|
||||
if (
|
||||
current_status and current_status.get("status") == "success"
|
||||
and re.search(rf"/actions/runs/{run_id}(?:/|$)",
|
||||
str(current_status.get("target_url", "")))
|
||||
current_status
|
||||
and current_status.get("status") == "success"
|
||||
and re.search(
|
||||
rf"/actions/runs/{run_id}(?:/|$)", str(current_status.get("target_url", ""))
|
||||
)
|
||||
and run.get("status") == "completed"
|
||||
and run.get("conclusion") == "success"
|
||||
and any(
|
||||
@@ -3993,19 +3972,35 @@ class GiteaConnector:
|
||||
for job in self.client.action_run_jobs(repository, run_id)
|
||||
)
|
||||
):
|
||||
return self._envelope(context, {
|
||||
"repositoryRef": repository_ref, "pr": number,
|
||||
"headSha": expected_head_sha, "requiredContext": MANAGED_VALIDATION_CONTEXT,
|
||||
"state": "success", "runId": run_id, "event": "pull_request",
|
||||
"reused": True,
|
||||
}, source=f"gitea:{repository_ref}")
|
||||
return self._envelope(
|
||||
context,
|
||||
{
|
||||
"repositoryRef": repository_ref,
|
||||
"pr": number,
|
||||
"headSha": expected_head_sha,
|
||||
"requiredContext": MANAGED_VALIDATION_CONTEXT,
|
||||
"state": "success",
|
||||
"runId": run_id,
|
||||
"event": "pull_request",
|
||||
"reused": True,
|
||||
},
|
||||
source=f"gitea:{repository_ref}",
|
||||
)
|
||||
if run.get("status") != "completed":
|
||||
return self._envelope(context, {
|
||||
"repositoryRef": repository_ref, "pr": number,
|
||||
"headSha": expected_head_sha, "requiredContext": MANAGED_VALIDATION_CONTEXT,
|
||||
"state": "pending", "runId": run_id, "event": "pull_request",
|
||||
"reused": True,
|
||||
}, source=f"gitea:{repository_ref}")
|
||||
return self._envelope(
|
||||
context,
|
||||
{
|
||||
"repositoryRef": repository_ref,
|
||||
"pr": number,
|
||||
"headSha": expected_head_sha,
|
||||
"requiredContext": MANAGED_VALIDATION_CONTEXT,
|
||||
"state": "pending",
|
||||
"runId": run_id,
|
||||
"event": "pull_request",
|
||||
"reused": True,
|
||||
},
|
||||
source=f"gitea:{repository_ref}",
|
||||
)
|
||||
break
|
||||
|
||||
if runs:
|
||||
@@ -4041,7 +4036,8 @@ class GiteaConnector:
|
||||
raise GiteaError(
|
||||
"GITEA_PR_REOPEN_FAILED",
|
||||
"PR was closed but could not be reopened; retry the exact PR reopen",
|
||||
retryable=True, safe_to_retry=True,
|
||||
retryable=True,
|
||||
safe_to_retry=True,
|
||||
) from exc
|
||||
trigger_method = "reopen_pull_request"
|
||||
run_id = 0
|
||||
@@ -4064,14 +4060,24 @@ class GiteaConnector:
|
||||
raise GiteaError(
|
||||
"GITEA_PR_RUN_NOT_VISIBLE",
|
||||
"PR reopened but its validation run is not visible yet; retry ensure",
|
||||
retryable=True, safe_to_retry=True,
|
||||
retryable=True,
|
||||
safe_to_retry=True,
|
||||
)
|
||||
return self._envelope(context, {
|
||||
"repositoryRef": repository_ref, "pr": number,
|
||||
"headSha": expected_head_sha, "requiredContext": MANAGED_VALIDATION_CONTEXT,
|
||||
"state": "pending", "runId": run_id, "event": "pull_request",
|
||||
"reused": False, "triggerMethod": trigger_method,
|
||||
}, source=f"gitea:{repository_ref}")
|
||||
return self._envelope(
|
||||
context,
|
||||
{
|
||||
"repositoryRef": repository_ref,
|
||||
"pr": number,
|
||||
"headSha": expected_head_sha,
|
||||
"requiredContext": MANAGED_VALIDATION_CONTEXT,
|
||||
"state": "pending",
|
||||
"runId": run_id,
|
||||
"event": "pull_request",
|
||||
"reused": False,
|
||||
"triggerMethod": trigger_method,
|
||||
},
|
||||
source=f"gitea:{repository_ref}",
|
||||
)
|
||||
|
||||
@governed_tool("gitea.pullrequest.close")
|
||||
def pull_request_close(
|
||||
@@ -4212,7 +4218,10 @@ class GiteaConnector:
|
||||
)
|
||||
|
||||
def _require_merge_eligible(
|
||||
self, context: ConnectorContext, repository_ref: str, number: int,
|
||||
self,
|
||||
context: ConnectorContext,
|
||||
repository_ref: str,
|
||||
number: int,
|
||||
expected_head_sha: str,
|
||||
) -> tuple[RegisteredRepository, str, int, str]:
|
||||
"""Authoritative server-side PR, protection, review and exact-run gate."""
|
||||
@@ -4281,8 +4290,7 @@ class GiteaConnector:
|
||||
raise GiteaError("GITEA_BLOCKING_REVIEW", "a reviewer requested changes")
|
||||
required_approvals = max(int(protection.get("required_approvals", 0) or 0), 0)
|
||||
approval_count = sum(
|
||||
str(item.get("state", "")).upper() == "APPROVED"
|
||||
for item in latest_reviews.values()
|
||||
str(item.get("state", "")).upper() == "APPROVED" for item in latest_reviews.values()
|
||||
)
|
||||
if approval_count < required_approvals:
|
||||
raise GiteaError(
|
||||
|
||||
Reference in new issue
Block a user