From 668c000394d20d899a88b7c7308411d897db6c38 Mon Sep 17 00:00:00 2001 From: host Date: Tue, 27 Oct 2026 11:12:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20GitHub=20App=20manifest=20=E6=89=A9?= =?UTF-8?q?=E5=88=B0=E4=B8=BB=E6=9C=BA=E6=9C=80=E5=A4=A7=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 仓库权限除 metadata 外全部拉到最高档(contents/pull_requests/ issues/actions/checks/workflows/administration 等全部 write, members 只读),事件补齐 push/check_run/workflow_run 等; 旧权限 contents/pull_requests write + issues read 不再是上限。 风险明示:administration=write 含删库/转移,secrets=write 含管理 secret,配 All repositories 时影响面为全账号仓库。 注意:改代码只改以后新建 App 的 manifest,线上 App (id 5476837) 仍需在 GitHub 设置里改权限并接受新权限。 --- cloud/github_app.py | 60 +++++++++++++++++++++++++++++++--- cloud/tests/test_github_app.py | 9 ++++- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/cloud/github_app.py b/cloud/github_app.py index a61ade9..04b946f 100644 --- a/cloud/github_app.py +++ b/cloud/github_app.py @@ -45,14 +45,66 @@ SETUP_STATE_TTL_SECONDS = 3600 DEFAULT_APP_NAME = "codex-app-server" DEFAULT_APP_URL = "https://github.com/openqj/codex-app-server" -# App 权限与事件:与当前 PAT 能力对齐(读仓库、推分支、建 PR、 -# 读 issue),不多要;webhook 只订阅 /fix-review 与 PR 相关事件。 +# App 权限与事件:主机最大权限(用户 2026-10-27 明确要求扩到 +# 最高、所有能力)。这是 manifest 的默认值,只影响以后新建的 +# App;已存在的线上 App(id 5476837)不会因改代码自动变权限, +# 必须在 GitHub App 设置里改权限并由安装方接受新权限后才生效。 +# 风险明示:administration=write 含改仓库设置/删库/转移, +# secrets=write 含管理仓库 secret,配 All repositories 安装会把 +# 影响面扩到该账号全部仓库——只装在自己信任的账号上。 +# organization/enterprise/billing 类权限不在此列:它们不属于 +# 主机跑任务的能力,且需组织/企业管理员另行审批,不应由一个 +# 代码托管 App 默认索取。 APP_PERMISSIONS = { + # 仓库:除 metadata(GitHub 自动只读)外全部拉到最高档。 + "actions": "write", + "actions_variables": "write", + "administration": "write", + "artifact_metadata": "write", + "attestations": "write", + "checks": "write", + "codespaces": "write", + "codespaces_metadata": "read", + "codespaces_secrets": "write", "contents": "write", + "dependabot_secrets": "write", + "deployments": "write", + "discussions": "write", + "environments": "write", + "issues": "write", + "merge_queues": "write", + "packages": "write", + "pages": "write", "pull_requests": "write", - "issues": "read", + "repository_advisories": "write", + "repository_custom_properties": "write", + "repository_hooks": "write", + "secret_scanning_alerts": "write", + "secrets": "write", + "security_events": "write", + "statuses": "write", + "vulnerability_alerts": "write", + "workflows": "write", + # 组织:只读成员,用于列协作者;不索取组织管理权。 + "members": "read", } -APP_EVENTS = ["issue_comment", "pull_request"] +APP_EVENTS = [ + "push", + "create", + "delete", + "pull_request", + "pull_request_review", + "pull_request_review_comment", + "issue_comment", + "issues", + "check_run", + "check_suite", + "workflow_run", + "release", + "deployment", + "deployment_status", + "discussion", +] class AppError(Exception): diff --git a/cloud/tests/test_github_app.py b/cloud/tests/test_github_app.py index 3eff05e..81f4bfa 100644 --- a/cloud/tests/test_github_app.py +++ b/cloud/tests/test_github_app.py @@ -86,9 +86,16 @@ class ManifestTestCase(unittest.TestCase): self.assertEqual(m["redirect_url"], BASE + "/github-app/callback") self.assertEqual(m["default_permissions"]["contents"], "write") self.assertEqual(m["default_permissions"]["pull_requests"], "write") - self.assertEqual(m["default_permissions"]["issues"], "read") + self.assertEqual(m["default_permissions"]["issues"], "write") + self.assertEqual(m["default_permissions"]["workflows"], "write") + self.assertEqual(m["default_permissions"]["administration"], "write") + self.assertEqual(m["default_permissions"]["actions"], "write") + self.assertEqual(m["default_permissions"]["checks"], "write") self.assertIn("issue_comment", m["default_events"]) self.assertIn("pull_request", m["default_events"]) + self.assertIn("push", m["default_events"]) + self.assertIn("check_run", m["default_events"]) + self.assertIn("workflow_run", m["default_events"]) self.assertFalse(m["public"]) def test_manifest_requires_base(self):