Skip to content

Build a multi-tenant EdgeOne GitHub App - #1

Merged
LYJW131 merged 2 commits into
mainfrom
agent/public-mvp
Aug 15, 2026
Merged

LYJW131 merged 2 commits into
mainfrom
agent/public-mvp

Conversation

@LYJW131

@LYJW131 LYJW131 commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Summary

  • build a standalone, multi-tenant Cloudflare Worker for a public GitHub App
  • verify GitHub App installations through user OAuth before allowing configuration
  • isolate each repository/EdgeOne project connection with its own webhook ID and bearer token
  • publish EdgeOne lifecycle events as GitHub Check Runs and GitHub Deployments
  • persist idempotency state in D1 and clean up data on GitHub App uninstall/repository removal
  • document the architecture, security model, GitHub App registration, Cloudflare deployment, and EdgeOne setup

Security

  • stores only SHA-256 digests of EdgeOne bearer tokens and setup-session tokens
  • uses signed OAuth state, HttpOnly cookies, CSRF tokens, bounded request bodies, and constant-time credential comparisons
  • verifies GitHub webhook signatures before processing lifecycle events
  • serializes concurrent EdgeOne deliveries through atomic D1 claims

Validation

  • pnpm test (12 tests)
  • pnpm typecheck
  • pnpm typegen:check
  • pnpm deploy:dry
  • initial migration applied to a fresh local D1 database
  • local Worker /health smoke test

Rollout note

This PR does not deploy a Worker or modify the existing single-tenant GitHub App. A new public GitHub App and production Cloudflare resources should be created from docs/operator-setup.md after review.

LYJW131 and others added 2 commits August 16, 2026 05:27
Add verified GitHub App setup, isolated EdgeOne connections, D1-backed deployment state, GitHub Checks and Deployments synchronization, lifecycle cleanup, CI, tests, and operator documentation.

Co-authored-by: Codex <codex@openai.com>
Use GitHub's supported installation listing flow, recover quickly from canceled EdgeOne deliveries, persist remote IDs during processing, and document the verified operator settings.

Co-authored-by: Codex <codex@openai.com>
@LYJW131
LYJW131 marked this pull request as ready for review August 15, 2026 23:20
@LYJW131
LYJW131 merged commit 940dccf into main Aug 15, 2026
1 check passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 798698d41f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/edgeone.ts
return githubDeploymentId;
};

[state.checkRunId, state.githubDeploymentId] = await Promise.all([checkRun(), deployment()]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the claim until both parallel writes settle

When either GitHub operation rejects while the other remains in flight, Promise.all rejects immediately and the catch block releases the deployment claim without waiting for the sibling operation. An EdgeOne retry can then start before that sibling has persisted its newly created Check Run or Deployment ID, causing a second remote object to be created. Wait for both operations to settle before releasing the claim while still propagating any failure.

Useful? React with 👍 / 👎.

Comment thread src/store.ts
eventType: string,
): Promise<boolean> {
const now = Date.now();
const staleBefore = now - 10 * 1000;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not expire active claims after ten seconds

If processing GitHub and D1 requests takes more than ten seconds, a second delivery can overwrite the still-active claim and perform the same GitHub writes concurrently. For deliveries with the same event type, the original request can then also clear the newer claim because completion is keyed only by that type, admitting further duplicates. Use a lease comfortably longer than the maximum processing window or add ownership tokens and lease renewal.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant