From 3953b6bdd232e81ee7f6e15cc2d0ab641db7a296 Mon Sep 17 00:00:00 2001 From: Jason Walker <913443@dadeschools.net> Date: Sun, 5 Jul 2026 02:10:18 -0400 Subject: [PATCH] feat: allow gitea.issue.comment for author and reviewer profiles (#137) - Add aliases 'issue.comment' and 'issue_comment' to GITEA_OPERATION_ALIASES so short names normalize to gitea.issue.comment - Grant 'issue.comment' (and short) in v2 example profiles for example-author and example-reviewer - Grant in gitea-mcp.example.json mdcps-reviewer - Update docs example profiles - Add test coverage for new aliases and normalization This enables gitea_create_issue_comment and list for profiles that include it, while preserving fail-closed for others and separation of duties (issue.comment does not imply pr.review etc). Closes #137 --- docs/gitea-execution-profiles.md | 2 +- gitea-mcp.example.json | 2 +- gitea-mcp.v2-contexts.example.json | 4 ++-- gitea_config.py | 2 ++ tests/test_op_normalization.py | 6 ++++++ 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/gitea-execution-profiles.md b/docs/gitea-execution-profiles.md index 42b671e..92a23bb 100644 --- a/docs/gitea-execution-profiles.md +++ b/docs/gitea-execution-profiles.md @@ -84,7 +84,7 @@ boundaries; they are the model, not a runtime enforcement mechanism yet. ### `gitea-reviewer` -- **allowed:** `read`, `pr.comment`, `pr.review`, `pr.approve`, `pr.request_changes` +- **allowed:** `read`, `pr.comment`, `pr.review`, `pr.approve`, `pr.request_changes`, `issue.comment` - **forbidden:** `pr.merge`, `branch.push` - `can_approve_prs`: `true` - `can_merge_prs`: `false` diff --git a/gitea-mcp.example.json b/gitea-mcp.example.json index 9b8adf6..c2b50f9 100644 --- a/gitea-mcp.example.json +++ b/gitea-mcp.example.json @@ -30,7 +30,7 @@ }, "default_owner": "MDCPS", "execution_profile": "mdcps-reviewer", - "allowed_operations": ["read", "review", "approve", "merge"], + "allowed_operations": ["read", "review", "approve", "merge", "issue.comment"], "forbidden_operations": ["branch.push", "pr.create"] }, "prgs-env": { diff --git a/gitea-mcp.v2-contexts.example.json b/gitea-mcp.v2-contexts.example.json index aace879..4bdad56 100644 --- a/gitea-mcp.v2-contexts.example.json +++ b/gitea-mcp.v2-contexts.example.json @@ -41,7 +41,7 @@ "execution_profile": "example-author", "audit_label": "example-author", "auth": { "type": "keychain", "id": "example-gitea-author-token" }, - "allowed_operations": ["read", "branch", "commit", "push", "open_pr", "comment"], + "allowed_operations": ["read", "branch", "commit", "push", "open_pr", "comment", "issue.comment"], "forbidden_operations": ["approve", "request_changes", "merge"] }, "example-reviewer": { @@ -52,7 +52,7 @@ "execution_profile": "example-reviewer", "audit_label": "example-reviewer", "auth": { "type": "keychain", "id": "example-gitea-reviewer-token" }, - "allowed_operations": ["read", "review", "comment", "approve", "request_changes", "merge"], + "allowed_operations": ["read", "review", "comment", "issue.comment", "approve", "request_changes", "merge"], "forbidden_operations": ["branch", "commit", "push", "open_pr"] } }, diff --git a/gitea_config.py b/gitea_config.py index 38f7b33..a4b0821 100644 --- a/gitea_config.py +++ b/gitea_config.py @@ -80,6 +80,8 @@ GITEA_OPERATION_ALIASES = { "read": "gitea.read", "review": "gitea.pr.review", "comment": "gitea.pr.comment", + "issue.comment": "gitea.issue.comment", + "issue_comment": "gitea.issue.comment", "approve": "gitea.pr.approve", "request_changes": "gitea.pr.request_changes", "merge": "gitea.pr.merge", diff --git a/tests/test_op_normalization.py b/tests/test_op_normalization.py index 70c4ec5..b454294 100644 --- a/tests/test_op_normalization.py +++ b/tests/test_op_normalization.py @@ -47,6 +47,8 @@ class TestNormalizeOperation(unittest.TestCase): "request_changes": "gitea.pr.request_changes", "review": "gitea.pr.review", "comment": "gitea.pr.comment", + "issue.comment": "gitea.issue.comment", + "issue_comment": "gitea.issue.comment", "read": "gitea.read", } for legacy, canonical in expected.items(): @@ -58,6 +60,10 @@ class TestNormalizeOperation(unittest.TestCase): self.assertEqual(normalize_operation("push"), "gitea.branch.push") self.assertEqual(normalize_operation("open_pr"), "gitea.pr.create") + def test_issue_comment_alias(self): + self.assertEqual(normalize_operation("issue.comment"), "gitea.issue.comment") + self.assertEqual(normalize_operation("issue_comment"), "gitea.issue.comment") + def test_unknown_unqualified_op_fails_closed(self): with self.assertRaises(ConfigError): normalize_operation("frobnicate") -- 2.43.7