← ~/work

Case study2026Reviewer and org admin, HNG Zedu

Zedu review infrastructure

PR review for an intern cohort: safe CI for forks, and real devices in the browser

Role
Reviewer and org admin, HNG Zedu
Stack
GitHub Actions · Docker · Coolify · noVNC
Status
Shipped
Reading
2 min
Zedu review infrastructure · fork PR → checks → device in the browser4 repos · workflows pinned by SHA
internfork PR
trusted · pull_request_targetrules · routing · approvalnever checks out PR code
untrusted · read-onlySemgrep · ClamAV · Gitleaks · Trivy
reviewer queue/claim · /releasemax 5 unclaimed per team
/test android · /test desktopemulator or desktopstreamed over noVNC
reviewertests in the browser
Sessions: reviewers team only, per-session token, read-only container, egress firewall, 30-minute cap.

The review pipeline behind the HNG Zedu org: shared GitHub Actions workflows for the web, mobile, desktop and backend repos, and device previews that boot an Android emulator or a Linux desktop from a PR comment and stream it to the reviewer's browser.

Problem

Intern teams open pull requests from forks, many of them, all at once. Fork PRs can't safely get write access or secrets, yet reviewers still need checks, routing and builds. And to review a mobile or desktop change, a reviewer had to download a build or wait on a hosted device service.

Approach

One repo, zedu-ci, holds reusable workflows that every product repo calls, each reference pinned to a full commit SHA. Jobs that need write access never check out PR code. Untrusted code only runs in read-only jobs that use config from the base branch.

text
/test android    →  Android 14 emulator on KVM, streamed over noVNC
/test desktop    →  Linux desktop session with the PR's build
/claim /release  →  take or hand back a PR in the reviewer queue

Design decisions

Split trusted and untrusted work

PR rules, team routing, lead approval and the fork build relay run with pull_request_target and never touch PR code. Scans run on the PR in read-only jobs: Semgrep, ClamAV and an obfuscation scan everywhere, plus Gitleaks on mobile and Trivy on desktop.

Devices in the browser, locked down

A /test comment starts a session on the PR's own build. Only the reviewers team gets in, through oauth2-proxy. Each session has its own 32-byte token. Containers run with a read-only root and dropped capabilities, egress firewall rules are re-applied at boot, and a session lasts 30 minutes with one 15-minute extension. It replaced uploading fork builds to Appetize.

A queue reviewers can work through

Each team holds at most five unclaimed PRs. Reviewers claim and release with a comment, and a merge needs one approval. Web previews deploy per team on the org's Coolify server.

What I built

  • Device previews end to end: the session agent, images and lockdown
  • Fork build relay, build gate, lead approval, team routing and the obfuscation scan
  • Per-team web previews on Coolify
  • Most of zedu-ci (113 of 167 commits); a co-maintainer built the assignment, nudge and feedback workflows

Outcome

  • 4 product repos call the shared workflows, every reference pinned by SHA
  • 30 workflow files in the public zedu-ci repo
  • Reviewers test Android and desktop changes from a PR comment, with nothing to download