Skip to content

Commit 63c4adb

Browse files
authored
Route monthly review to self-hosted Codex bridge
1 parent 7e2c806 commit 63c4adb

2 files changed

Lines changed: 112 additions & 2 deletions

File tree

.github/workflows/monthly_publish.yml

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ jobs:
2727
FIRESTORE_DOCUMENT: ${{ vars.FIRESTORE_DOCUMENT || 'CRYPTO_LEADER_ROTATION_LIVE_POOL' }}
2828
GCP_PROJECT_ID: ${{ vars.GCP_PROJECT_ID }}
2929
GCS_BUCKET: ${{ vars.GCS_BUCKET }}
30+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
31+
SELFHOSTED_CODEX_REVIEW_ENABLED: ${{ vars.SELFHOSTED_CODEX_REVIEW_ENABLED || 'true' }}
32+
SELFHOSTED_CODEX_REVIEW_REPOSITORY: ${{ vars.SELFHOSTED_CODEX_REVIEW_REPOSITORY || 'QuantStrategyLab/SelfHostedCodexAuditBridge' }}
33+
SELFHOSTED_CODEX_REVIEW_MODE: ${{ vars.SELFHOSTED_CODEX_REVIEW_MODE || 'review_and_fix' }}
34+
SELFHOSTED_CODEX_REVIEW_AUTO_MERGE: ${{ vars.SELFHOSTED_CODEX_REVIEW_AUTO_MERGE || 'false' }}
35+
LEGACY_AI_REVIEW_ENABLED: ${{ vars.LEGACY_AI_REVIEW_ENABLED || 'false' }}
3036

3137
steps:
3238
- name: Checkout
@@ -166,8 +172,100 @@ jobs:
166172
print(f"issue_url={issue['html_url']}", file=output)
167173
PY
168174
169-
- name: Trigger AI Monthly Review
170-
if: success() && env.PUBLISH_ENABLED != 'false'
175+
- name: Detect Self-hosted Review GitHub App Credentials
176+
id: codex_review_app_credentials
177+
if: success() && env.PUBLISH_ENABLED != 'false' && env.SELFHOSTED_CODEX_REVIEW_ENABLED != 'false'
178+
env:
179+
APP_ID: ${{ vars.CROSS_REPO_GITHUB_APP_ID }}
180+
APP_PRIVATE_KEY: ${{ secrets.CROSS_REPO_GITHUB_APP_PRIVATE_KEY }}
181+
run: |
182+
set -euo pipefail
183+
if [ -n "${APP_ID:-}" ] && [ -n "${APP_PRIVATE_KEY:-}" ]; then
184+
echo "available=true" >> "$GITHUB_OUTPUT"
185+
else
186+
echo "available=false" >> "$GITHUB_OUTPUT"
187+
fi
188+
189+
- name: Create GitHub App Token For Self-hosted Review
190+
id: codex_review_app_token
191+
if: steps.codex_review_app_credentials.outputs.available == 'true'
192+
continue-on-error: true
193+
uses: actions/create-github-app-token@v3
194+
with:
195+
app-id: ${{ vars.CROSS_REPO_GITHUB_APP_ID }}
196+
private-key: ${{ secrets.CROSS_REPO_GITHUB_APP_PRIVATE_KEY }}
197+
owner: ${{ github.repository_owner }}
198+
repositories: |
199+
SelfHostedCodexAuditBridge
200+
permission-contents: write
201+
202+
- name: Trigger Self-hosted Codex Monthly Review
203+
if: success() && env.PUBLISH_ENABLED != 'false' && env.SELFHOSTED_CODEX_REVIEW_ENABLED != 'false'
204+
env:
205+
APP_TOKEN: ${{ steps.codex_review_app_token.outputs.token }}
206+
CODEX_AUDIT_DISPATCH_TOKEN: ${{ secrets.CODEX_AUDIT_DISPATCH_TOKEN }}
207+
GITHUB_REPOSITORY: ${{ github.repository }}
208+
GITHUB_REF_NAME: ${{ github.ref_name }}
209+
ISSUE_NUMBER: ${{ steps.review_issue.outputs.issue_number }}
210+
ISSUE_URL: ${{ steps.review_issue.outputs.issue_url }}
211+
TARGET_REPOSITORY: ${{ env.SELFHOSTED_CODEX_REVIEW_REPOSITORY }}
212+
REVIEW_MODE: ${{ env.SELFHOSTED_CODEX_REVIEW_MODE }}
213+
AUTO_MERGE: ${{ env.SELFHOSTED_CODEX_REVIEW_AUTO_MERGE }}
214+
run: |
215+
set -euo pipefail
216+
python - <<'PY'
217+
import json
218+
import os
219+
import re
220+
import urllib.request
221+
222+
token = os.environ.get("APP_TOKEN", "").strip() or os.environ.get("CODEX_AUDIT_DISPATCH_TOKEN", "").strip()
223+
if not token:
224+
raise RuntimeError(
225+
"Self-hosted Codex review dispatch requires either a GitHub App token "
226+
"or CODEX_AUDIT_DISPATCH_TOKEN"
227+
)
228+
target_repository = os.environ["TARGET_REPOSITORY"].strip()
229+
if not re.fullmatch(r"[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+", target_repository):
230+
raise RuntimeError(f"Invalid self-hosted review repository: {target_repository!r}")
231+
mode = os.environ["REVIEW_MODE"].strip() or "review_and_fix"
232+
if mode not in {"review_only", "review_and_fix"}:
233+
raise RuntimeError(f"Unsupported self-hosted review mode: {mode}")
234+
235+
payload = {
236+
"event_type": "monthly-review-created",
237+
"client_payload": {
238+
"source_repo": os.environ["GITHUB_REPOSITORY"],
239+
"source_ref": os.environ["GITHUB_REF_NAME"],
240+
"issue_number": os.environ["ISSUE_NUMBER"],
241+
"issue_url": os.environ["ISSUE_URL"],
242+
"mode": mode,
243+
"auto_merge": os.environ["AUTO_MERGE"].strip().lower() == "true",
244+
},
245+
}
246+
request = urllib.request.Request(
247+
f"https://api.github.com/repos/{target_repository}/dispatches",
248+
data=json.dumps(payload).encode("utf-8"),
249+
method="POST",
250+
headers={
251+
"Authorization": f"Bearer {token}",
252+
"Accept": "application/vnd.github+json",
253+
"Content-Type": "application/json",
254+
"X-GitHub-Api-Version": "2022-11-28",
255+
"User-Agent": "crypto-leader-rotation-monthly-publish",
256+
},
257+
)
258+
with urllib.request.urlopen(request) as response:
259+
if response.status not in (201, 204):
260+
raise RuntimeError(f"Unexpected dispatch status: {response.status}")
261+
print(
262+
f"Dispatched self-hosted Codex review for issue #{os.environ['ISSUE_NUMBER']} "
263+
f"to {target_repository}"
264+
)
265+
PY
266+
267+
- name: Trigger Legacy AI Monthly Review
268+
if: success() && env.PUBLISH_ENABLED != 'false' && env.LEGACY_AI_REVIEW_ENABLED == 'true'
171269
env:
172270
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
173271
GITHUB_REPOSITORY: ${{ github.repository }}

tests/test_monthly_publish_workflow_config.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ def test_monthly_review_issue_creation_does_not_require_gh_cli(self) -> None:
3636
self.assertIn("https://api.github.com/repos/{repository}", workflow)
3737
self.assertIn('GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}', workflow)
3838
self.assertIn("issue_number=", workflow)
39+
self.assertIn("SELFHOSTED_CODEX_REVIEW_REPOSITORY", workflow)
40+
self.assertIn("QuantStrategyLab/SelfHostedCodexAuditBridge", workflow)
41+
self.assertIn("CROSS_REPO_GITHUB_APP_ID", workflow)
42+
self.assertIn("CROSS_REPO_GITHUB_APP_PRIVATE_KEY", workflow)
43+
self.assertIn("actions/create-github-app-token@v3", workflow)
44+
self.assertIn("SelfHostedCodexAuditBridge", workflow)
45+
self.assertIn("permission-contents: write", workflow)
46+
self.assertIn("APP_TOKEN", workflow)
47+
self.assertIn("CODEX_AUDIT_DISPATCH_TOKEN", workflow)
48+
self.assertIn("monthly-review-created", workflow)
49+
self.assertIn("/repos/{target_repository}/dispatches", workflow)
50+
self.assertIn("LEGACY_AI_REVIEW_ENABLED == 'true'", workflow)
3951
self.assertIn("/actions/workflows/ai_review.yml/dispatches", workflow)
4052

4153
def test_ai_review_workflow_supports_dispatch_and_comment_posting(self) -> None:

0 commit comments

Comments
 (0)