cyrus-setup-github
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCRITICAL: Never use , , or tools on or any file inside . Use only commands (, , etc.) to interact with env files — secrets must never be read into the conversation context.
ReadEditWrite~/.cyrus/.env~/.cyrus/Bashgrepprintf >>重要提示:切勿在或内的任何文件上使用、或工具。仅使用Bash命令(如、等)与环境文件交互——机密信息绝不能被读取到对话上下文中。
~/.cyrus/.env~/.cyrus/ReadEditWritegrepprintf >>Setup GitHub
GitHub配置
Configures GitHub CLI and git so Cyrus can create branches, commits, and pull requests. Optionally creates a GitHub App so Cyrus can receive and respond to @mentions in PR comments and reviews, automate rebases and merges, and auto-fix based on CI failures (coming soon).
配置GitHub CLI与git,使Cyrus能够创建分支、提交和拉取请求(PR)。可选创建GitHub App,让Cyrus能够接收并响应PR评论与评审中的@提及,自动执行变基与合并,以及基于CI失败进行自动修复(即将推出)。
Part A: GitHub CLI + Git Config (Outbound)
第一部分:GitHub CLI + Git配置(对外操作)
Step 1: Check Existing Configuration
步骤1:检查现有配置
Check if is already authenticated:
ghbash
gh auth status 2>&1If authenticated, check git config:
bash
git config --global user.name
git config --global user.emailIf both auth and git config are set, inform the user:
ghGitHub is already configured. Skipping to webhook setup.
Skip to Part B.
检查是否已完成认证:
ghbash
gh auth status 2>&1如果已认证,检查git配置:
bash
git config --global user.name
git config --global user.email如果认证与git配置均已设置,告知用户:
ghGitHub已完成配置。跳至webhook设置环节。
直接进入第二部分。
Step 2: Authenticate GitHub CLI
步骤2:认证GitHub CLI
If is not authenticated:
ghbash
gh auth loginThis opens an interactive browser flow. Let the user complete it.
After completion, verify:
bash
gh auth status如果未认证:
ghbash
gh auth login这会打开一个交互式浏览器流程。请用户完成该流程。
完成后,验证认证状态:
bash
gh auth statusStep 3: Configure Git Identity
步骤3:配置Git身份信息
If git user name or email are not set, ask the user for their preferred values:
What name should appear on commits made by Cyrus? (e.g., your name, or "Cyrus Bot")
What email should appear on commits? (e.g., your email, or a noreply address)
Then set them:
bash
git config --global user.name "<name>"
git config --global user.email "<email>"如果git用户名或邮箱未设置,向用户询问偏好值:
Cyrus提交的代码应显示什么名称? (例如:你的姓名,或"Cyrus Bot")
提交的代码应显示什么邮箱? (例如:你的邮箱,或noreply地址)
然后设置这些值:
bash
git config --global user.name "<name>"
git config --global user.email "<email>"Step 4: Verify
步骤4:验证配置
bash
gh auth status
git config --global user.name
git config --global user.emailbash
gh auth status
git config --global user.name
git config --global user.emailPart B: GitHub App + Webhooks (Inbound — Optional)
第二部分:GitHub App + Webhook(对内操作——可选)
Ask the user:
Do you want Cyrus to respond to GitHub @mentions in PR comments and reviews?
- Yes — enable @mentions: Creates a GitHub App so Cyrus can receive PR comments and reviews via webhooks, respond when @mentioned, and act on "changes requested" reviews.
- No — PRs only: Cyrus will create branches, commits, and PRs but won't respond to comments.
If No → skip to Completion.
询问用户:
是否希望Cyrus响应GitHub PR评论与评审中的@提及?
- 是——启用@提及:创建GitHub App,使Cyrus能够通过webhook接收PR评论与评审,在被@提及时做出响应,并根据“请求更改”的评审采取行动。
- 否——仅处理PR:Cyrus将创建分支、提交和PR,但不会响应评论。
如果选择否 → 跳至完成环节。
Step 5: Check Existing Webhook Config
步骤5:检查现有Webhook配置
bash
grep -c '^GITHUB_WEBHOOK_SECRET=.' ~/.cyrus/.env 2>/dev/null
grep -c '^GITHUB_APP_ID=.' ~/.cyrus/.env 2>/dev/null
grep -c '^GITHUB_APP_INSTALLATION_ID=.' ~/.cyrus/.env 2>/dev/null
test -f ~/.cyrus/github-app.pem && echo "PEM exists" || echo "PEM missing"If all four checks pass (1, 1, 1, "PEM exists"), skip to Completion — webhooks are already configured.
bash
grep -c '^GITHUB_WEBHOOK_SECRET=.' ~/.cyrus/.env 2>/dev/null
grep -c '^GITHUB_APP_ID=.' ~/.cyrus/.env 2>/dev/null
grep -c '^GITHUB_APP_INSTALLATION_ID=.' ~/.cyrus/.env 2>/dev/null
test -f ~/.cyrus/github-app.pem && echo "PEM exists" || echo "PEM missing"如果四项检查均通过(结果为1、1、1、"PEM exists"),跳至完成环节——webhook已配置完成。
Step 6: Collect Inputs
步骤6:收集输入信息
Read the webhook base URL:
bash
grep '^CYRUS_BASE_URL=' ~/.cyrus/.env | cut -d= -f2-If is not set, stop and tell the user to run the endpoint setup step first.
CYRUS_BASE_URLUse the value from the orchestrator (set in Step 0 of ). If not available, ask:
AGENT_NAME/cyrus-setupWhat should the GitHub App be named? (e.g., "Cyrus", "My Code Agent")
Important — GitHub @mention autocomplete quirk: GitHub's autocomplete in PR comments only suggests real GitHub user accounts, not App bots. This means won't appear in the autocomplete dropdown unless a GitHub user with that exact name exists. The mention still works if typed manually, but for the best experience:
@your-botBefore choosing a name, check if the same name is available as a GitHub username at. If it is:https://github.com/<name>
- Create a free GitHub user account with that name
- Invite it to your org and/or repo as a collaborator
- Set
to that username (the one users will type in @mentions, notGITHUB_BOT_USERNAME)<slug>[bot]This is the simplest way to get autocomplete working — a silly GitHub limitation, but the known workaround.Without a matching GitHub user, @mentions still work if typed manually, but won't autocomplete. In that case users would need to set up co-authorship (via a git message template orhook addingprepare-commit-msg) to get the bot's name showing as a repo contributor, which is more involved.Co-authored-by:
Ask:
Where should the GitHub App be created?
- Personal account (github.com/settings/apps)
- Organization — which org? (github.com/organizations/
/settings/apps)<ORG>
Store the org name if applicable.
Ask:
What homepage URL should the GitHub App use? This is displayed on the app's settings page as its website. It has no functional impact — GitHub just shows it as a link. Most users use their company website, GitHub org page, or any placeholder URL.(e.g.,, your company URL, or justhttps://github.com/your-org)https://example.com
读取webhook基础URL:
bash
grep '^CYRUS_BASE_URL=' ~/.cyrus/.env | cut -d= -f2-如果未设置,停止操作并告知用户先运行端点设置步骤。
CYRUS_BASE_URL使用编排器中的值(在的步骤0中设置)。如果不可用,询问用户:
AGENT_NAME/cyrus-setupGitHub App应命名为什么?(例如:"Cyrus"、"My Code Agent")
重要提示——GitHub@提及自动补全的特殊情况: GitHub在PR评论中的自动补全仅会推荐真实的GitHub用户账户,而非App机器人。这意味着除非存在同名的GitHub用户,否则不会出现在自动补全下拉列表中。手动输入提及仍然有效,但为获得最佳体验:
@your-bot选择名称前,请访问检查该名称是否可用作GitHub用户名。如果可用:https://github.com/<name>
- 创建一个免费的GitHub用户账户并使用该名称
- 将其邀请到你的组织和/或仓库作为协作者
- 将
设置为该用户名(即用户在@提及中会输入的名称,不是GITHUB_BOT_USERNAME)<slug>[bot]这是实现自动补全最简单的方法——这是GitHub的一个小限制,但目前已知的解决方法就是如此。如果没有匹配的GitHub用户,手动输入@提及仍然有效,但不会自动补全。这种情况下,用户需要设置共同作者身份(通过git消息模板或钩子添加prepare-commit-msg),才能让机器人名称显示为仓库贡献者,这会更复杂。Co-authored-by:
询问用户:
GitHub App应创建在哪里?
- 个人账户(github.com/settings/apps)
- 组织——哪个组织?(github.com/organizations/
/settings/apps)<ORG>
如果是组织,存储组织名称。
询问用户:
GitHub App应使用什么主页URL? 该URL会显示在应用的设置页面上作为其官网。它没有功能影响——GitHub仅将其显示为链接。大多数用户会使用公司官网、GitHub组织页面或任何占位符URL。(例如:、你的公司网址,或仅https://github.com/your-org)https://example.com
Step 7: Build Manifest JSON
步骤7:构建清单JSON
Construct the manifest, substituting , , and :
AGENT_NAMEHOMEPAGE_URLCYRUS_BASE_URLjson
{
"name": "<AGENT_NAME>",
"url": "<HOMEPAGE_URL>",
"redirect_url": "http://localhost:8976",
"hook_attributes": {
"url": "<CYRUS_BASE_URL>/github-webhook",
"active": true
},
"public": false,
"default_permissions": {
"contents": "write",
"issues": "write",
"pull_requests": "write",
"repository_hooks": "write"
},
"default_events": [
"issue_comment",
"organization",
"pull_request_review",
"pull_request_review_comment",
"repository"
]
}Note: is required by GitHub's manifest flow. The actual redirect will include a parameter appended to this URL — the code is what matters, not the destination page.
redirect_url?code=构建清单,替换、和:
AGENT_NAMEHOMEPAGE_URLCYRUS_BASE_URLjson
{
"name": "<AGENT_NAME>",
"url": "<HOMEPAGE_URL>",
"redirect_url": "http://localhost:8976",
"hook_attributes": {
"url": "<CYRUS_BASE_URL>/github-webhook",
"active": true
},
"public": false,
"default_permissions": {
"contents": "write",
"issues": "write",
"pull_requests": "write",
"repository_hooks": "write"
},
"default_events": [
"issue_comment",
"organization",
"pull_request_review",
"pull_request_review_comment",
"repository"
]
}注意: 是GitHub清单流程所必需的。实际重定向会在该URL后附加参数——重要的是这个code,而非目标页面。
redirect_url?code=Step 8: Create GitHub App via Manifest
步骤8:通过清单创建GitHub App
GitHub's manifest flow works by POSTing a form with a field to the app creation URL. After the user approves, GitHub redirects to a URL containing a parameter.
manifestcodeDetermine the creation URL:
- Personal:
https://github.com/settings/apps/new - Organization:
https://github.com/organizations/<ORG>/settings/apps/new
GitHub's manifest flow requires a form POST with a field to the creation URL — the page itself does not have a manifest input field. All paths use the same helper HTML page approach.
manifestFirst, create the helper page and serve it via a local web server. This works for both local and remote/headless setups (e.g., tmux/SSH into a server). The manifest JSON must be HTML-entity-escaped (replace with ) since it's placed in an HTML attribute:
""bash
undefinedGitHub的清单流程是通过向应用创建URL发送带有字段的表单POST请求来实现的。用户批准后,GitHub会重定向到包含参数的URL。
manifestcode确定创建URL:
- 个人账户:
https://github.com/settings/apps/new - 组织:
https://github.com/organizations/<ORG>/settings/apps/new
GitHub的清单流程需要向创建URL发送表单POST请求并携带字段——页面本身并没有清单输入框。所有路径都使用相同的辅助HTML页面方法。
manifest首先,创建辅助页面并通过本地Web服务器提供服务。这适用于本地和远程/无头设置(例如:通过tmux/SSH连接到服务器)。清单JSON必须进行HTML实体转义(将替换为),因为它会被放置在HTML属性中:
""bash
undefinedEscape the manifest JSON for safe embedding in an HTML attribute
转义清单JSON以安全嵌入HTML属性
MANIFEST_HTML_ESCAPED=$(echo '<MANIFEST_JSON>' | sed 's/"/"/g')
cat > /tmp/github-app-manifest.html << HTMLEOF
<form method="post" action="<CREATION_URL>">
<input type="hidden" name="manifest" value="$MANIFEST_HTML_ESCAPED">
<p>Click the button to create the GitHub App:</p>
<button type="submit" style="font-size:18px;padding:12px 24px;">Create GitHub App</button>
</form>
HTMLEOFMANIFEST_HTML_ESCAPED=$(echo '<MANIFEST_JSON>' | sed 's/"/"/g')
cat > /tmp/github-app-manifest.html << HTMLEOF
<form method="post" action="<CREATION_URL>">
<input type="hidden" name="manifest" value="$MANIFEST_HTML_ESCAPED">
<p>点击按钮创建GitHub App:</p>
<button type="submit" style="font-size:18px;padding:12px 24px;">Create GitHub App</button>
</form>
HTMLEOFServe the page on a local port (works for headless/remote setups)
在本地端口提供页面服务(适用于无头/远程设置)
python3 -m http.server 8976 --directory /tmp &
HTTP_SERVER_PID=$!
echo "Serving at http://localhost:8976/github-app-manifest.html"
After the user completes the flow, stop the server:
```bash
kill $HTTP_SERVER_PID 2>/dev/nullChoose the automation path based on what's available:
- If MCP tools are available → use Path A-1
claude-in-chrome - If is installed and a Chrome debug session is connected → use Path A-2
agent-browser - Otherwise → use Path B (manual)
Path A-1 (claude-in-chrome):
- Navigate to
http://localhost:8976/github-app-manifest.html - Click the submit button to POST the manifest to GitHub
- GitHub shows a confirmation page — click Create GitHub App
- After redirect, extract the parameter from the URL
code
Path A-2 (agent-browser):
Same flow via — navigate to the helper page, click submit, then click Create.
agent-browserPath B (manual):
Tell the user:
- Open
in your browser and click the buttonhttp://localhost:8976/github-app-manifest.html- Review the permissions on GitHub and click Create GitHub App
- After redirect, copy the entire URL from the browser address bar and paste it here
Extract the parameter from the redirect URL.
codepython3 -m http.server 8976 --directory /tmp &
HTTP_SERVER_PID=$!
echo "Serving at http://localhost:8976/github-app-manifest.html"
用户完成流程后,停止服务器:
```bash
kill $HTTP_SERVER_PID 2>/dev/null根据可用工具选择自动化路径:
- 如果MCP工具可用 → 使用路径A-1
claude-in-chrome - 如果已安装且已连接Chrome调试会话 → 使用路径A-2
agent-browser - 否则 → 使用路径B(手动操作)
路径A-1(claude-in-chrome):
- 导航至
http://localhost:8976/github-app-manifest.html - 点击提交按钮将清单POST到GitHub
- GitHub会显示确认页面——点击Create GitHub App
- 重定向后,从URL中提取参数
code
路径A-2(agent-browser):
通过执行相同流程——导航至辅助页面,点击提交,然后点击Create。
agent-browser路径B(手动操作):
告知用户:
- 在浏览器中打开
并点击按钮http://localhost:8976/github-app-manifest.html- 在GitHub上查看权限并点击Create GitHub App
- 重定向后,复制浏览器地址栏中的完整URL并粘贴到此处
从重定向URL中提取参数。
codeStep 9: Exchange Code for Credentials
步骤9:将Code兑换为凭证
IMPORTANT: The endpoint is one-time-use. Call it exactly once.
/app-manifests/<CODE>/conversionsbash
undefined重要提示: 端点只能使用一次。请准确调用一次。
/app-manifests/<CODE>/conversionsbash
undefinedStore the full response temporarily (one-time-use endpoint — do NOT call twice)
临时存储完整响应(一次性端点——请勿调用两次)
gh api /app-manifests/<CODE>/conversions --method POST > /tmp/github-app-response.json
gh api /app-manifests/<CODE>/conversions --method POST > /tmp/github-app-response.json
Extract values (these are all secrets — handle via Bash only)
提取值(这些均为机密信息——仅通过Bash处理)
GITHUB_APP_ID=$(cat /tmp/github-app-response.json | jq -r '.id')
GITHUB_APP_SLUG=$(cat /tmp/github-app-response.json | jq -r '.slug')
GITHUB_WEBHOOK_SECRET=$(cat /tmp/github-app-response.json | jq -r '.webhook_secret')
GITHUB_APP_PEM=$(cat /tmp/github-app-response.json | jq -r '.pem')
GITHUB_APP_ID=$(cat /tmp/github-app-response.json | jq -r '.id')
GITHUB_APP_SLUG=$(cat /tmp/github-app-response.json | jq -r '.slug')
GITHUB_WEBHOOK_SECRET=$(cat /tmp/github-app-response.json | jq -r '.webhook_secret')
GITHUB_APP_PEM=$(cat /tmp/github-app-response.json | jq -r '.pem')
Clean up
清理文件
rm /tmp/github-app-response.json
undefinedrm /tmp/github-app-response.json
undefinedStep 10: Write Credentials to Env
步骤10:将凭证写入环境文件
bash
undefinedbash
undefinedEnsure directory exists (may not if running standalone outside cyrus-setup)
确保目录存在(如果在cyrus-setup之外独立运行,可能不存在)
mkdir -p ~/.cyrus
mkdir -p ~/.cyrus
Webhook secret (for signature verification)
Webhook密钥(用于签名验证)
printf 'GITHUB_WEBHOOK_SECRET=%s\n' "$GITHUB_WEBHOOK_SECRET" >> ~/.cyrus/.env
printf 'GITHUB_WEBHOOK_SECRET=%s\n' "$GITHUB_WEBHOOK_SECRET" >> ~/.cyrus/.env
App ID (for token minting)
App ID(用于生成令牌)
printf 'GITHUB_APP_ID=%s\n' "$GITHUB_APP_ID" >> ~/.cyrus/.env
printf 'GITHUB_APP_ID=%s\n' "$GITHUB_APP_ID" >> ~/.cyrus/.env
Bot username (for mention filtering — see note below about GitHub autocomplete)
机器人用户名(用于过滤提及——请参阅下方关于GitHub自动补全的说明)
printf 'GITHUB_BOT_USERNAME=%s\n' "$GITHUB_APP_SLUG" >> ~/.cyrus/.env
printf 'GITHUB_BOT_USERNAME=%s\n' "$GITHUB_APP_SLUG" >> ~/.cyrus/.env
Private key (multi-line — stored as a separate file)
私钥(多行——存储为单独文件)
printf '%s\n' "$GITHUB_APP_PEM" > ~/.cyrus/github-app.pem
chmod 600 ~/.cyrus/github-app.pem
printf '%s\n' "$GITHUB_APP_PEM" > ~/.cyrus/github-app.pem
chmod 600 ~/.cyrus/github-app.pem
Ensure self-hosted mode is active (required for signature verification)
确保启用自托管模式(签名验证所需)
grep -q '^CYRUS_HOST_EXTERNAL=' ~/.cyrus/.env || printf 'CYRUS_HOST_EXTERNAL=true\n' >> ~/.cyrus/.env
Verify all values were written:
```bash
grep -c '^GITHUB_WEBHOOK_SECRET=.' ~/.cyrus/.env
grep -c '^GITHUB_APP_ID=.' ~/.cyrus/.env
grep -c '^GITHUB_BOT_USERNAME=.' ~/.cyrus/.env
test -f ~/.cyrus/github-app.pem && echo "PEM exists" || echo "PEM missing"All checks must pass (return 1, 1, 1, "PEM exists").
grep -q '^CYRUS_HOST_EXTERNAL=' ~/.cyrus/.env || printf 'CYRUS_HOST_EXTERNAL=true\n' >> ~/.cyrus/.env
验证所有值已写入:
```bash
grep -c '^GITHUB_WEBHOOK_SECRET=.' ~/.cyrus/.env
grep -c '^GITHUB_APP_ID=.' ~/.cyrus/.env
grep -c '^GITHUB_BOT_USERNAME=.' ~/.cyrus/.env
test -f ~/.cyrus/github-app.pem && echo "PEM exists" || echo "PEM missing"所有检查必须通过(返回1、1、1、"PEM exists")。
Step 11: Install App on Repositories
步骤11:在仓库上安装App
The GitHub App must be installed on the repositories Cyrus will monitor.
Go to:https://github.com/apps/<GITHUB_APP_SLUG>/installations/newSelect which repositories (or "All repositories") and click Install.
Or via browser automation (navigate to URL, select repos, click Install).
After installation, capture the installation ID:
bash
undefinedGitHub App必须安装在Cyrus将监控的仓库上。
访问:https://github.com/apps/<GITHUB_APP_SLUG>/installations/new选择要安装的仓库(或“所有仓库”)并点击Install。
或通过浏览器自动化完成(导航至URL,选择仓库,点击Install)。
安装完成后,获取安装ID:
bash
undefinedRe-read GITHUB_APP_ID from .env (shell vars don't persist between blocks)
从.env重新读取GITHUB_APP_ID(shell变量不会在块之间持久化)
GITHUB_APP_ID=$(grep '^GITHUB_APP_ID=' ~/.cyrus/.env | cut -d= -f2-)
GITHUB_APP_ID=$(grep '^GITHUB_APP_ID=' ~/.cyrus/.env | cut -d= -f2-)
Generate a JWT to authenticate as the app
生成JWT以作为App进行认证
GITHUB_APP_JWT=$(node -e "
const crypto = require('crypto');
const fs = require('fs');
const key = fs.readFileSync(process.env.HOME + '/.cyrus/github-app.pem', 'utf8');
const now = Math.floor(Date.now()/1000);
const header = Buffer.from(JSON.stringify({alg:'RS256',typ:'JWT'})).toString('base64url');
const payload = Buffer.from(JSON.stringify({iat:now-60,exp:now+600,iss:'$GITHUB_APP_ID'})).toString('base64url');
const sig = crypto.createSign('RSA-SHA256').update(header+'.'+payload).sign(key,'base64url');
console.log(header+'.'+payload+'.'+sig);
")
GITHUB_APP_JWT=$(node -e "
const crypto = require('crypto');
const fs = require('fs');
const key = fs.readFileSync(process.env.HOME + '/.cyrus/github-app.pem', 'utf8');
const now = Math.floor(Date.now()/1000);
const header = Buffer.from(JSON.stringify({alg:'RS256',typ:'JWT'})).toString('base64url');
const payload = Buffer.from(JSON.stringify({iat:now-60,exp:now+600,iss:'$GITHUB_APP_ID'})).toString('base64url');
const sig = crypto.createSign('RSA-SHA256').update(header+'.'+payload).sign(key,'base64url');
console.log(header+'.'+payload+'.'+sig);
")
List installations — if multiple, show all and let user pick
列出所有安装——如果有多个,显示全部并让用户选择
INSTALLATIONS=$(curl -s -H "Authorization: Bearer $GITHUB_APP_JWT" -H "Accept: application/vnd.github+json" https://api.github.com/app/installations)
echo "$INSTALLATIONS" | jq '.[] | {id, account: .account.login}'
If there are multiple installations, ask the user which one to use. Then write the installation ID:
```bash
printf 'GITHUB_APP_INSTALLATION_ID=%s\n' "<INSTALLATION_ID>" >> ~/.cyrus/.envVerify:
bash
grep -c '^GITHUB_APP_INSTALLATION_ID=.' ~/.cyrus/.envMust return 1.
INSTALLATIONS=$(curl -s -H "Authorization: Bearer $GITHUB_APP_JWT" -H "Accept: application/vnd.github+json" https://api.github.com/app/installations)
echo "$INSTALLATIONS" | jq '.[] | {id, account: .account.login}'
如果有多个安装,询问用户使用哪一个。然后写入安装ID:
```bash
printf 'GITHUB_APP_INSTALLATION_ID=%s\n' "<INSTALLATION_ID>" >> ~/.cyrus/.env验证:
bash
grep -c '^GITHUB_APP_INSTALLATION_ID=.' ~/.cyrus/.env必须返回1。
Completion
完成
✓ GitHub CLI authenticated ✓ Git identity configured:<<name>>
If webhooks were enabled:
✓ GitHub App created:✓ Webhook secret and app credentials saved to<GITHUB_APP_SLUG>✓ Private key saved to~/.cyrus/.env✓ App installed (installation ID:~/.cyrus/github-app.pem) ✓ Cyrus will respond to<GITHUB_APP_INSTALLATION_ID>mentions in PR comments@<GITHUB_BOT_USERNAME>
Note: The webhook URL will only respond successfully once Cyrus is running. If GitHub shows a webhook delivery failure during setup, it will retry automatically once Cyrus starts.
✓ GitHub CLI已认证 ✓ Git身份信息已配置:<<name>>
如果启用了webhook:
✓ GitHub App已创建:✓ Webhook密钥与App凭证已保存至<GITHUB_APP_SLUG>✓ 私钥已保存至~/.cyrus/.env✓ App已安装(安装ID:~/.cyrus/github-app.pem) ✓ Cyrus将响应PR评论中的<GITHUB_APP_INSTALLATION_ID>提及@<GITHUB_BOT_USERNAME>
注意: 只有当Cyrus运行时,webhook URL才会成功响应。如果设置过程中GitHub显示webhook交付失败,Cyrus启动后会自动重试。