Paste your ESPHome YAML in the browser to compile in the cloud and download firmware.
- ✅ Automatically detects and collects
!secretplaceholders in order of appearance, with local caching to avoid re-entering values on subsequent compilations. - ✅ Generates a 16-character alphanumeric archive password, customizable and locally persisted; firmware artifacts are encrypted zip files named
firmware-<request_id>-password.zip. - ✅ Automatically saves YAML drafts, archive passwords, ESPHome version selection, and recent compilation status; recovers on page refresh.
- ✅ Supports selecting common ESPHome versions from a dropdown or manually entering a specific version number for historical builds.
- ✅ Retains GitHub Workflow link on failure for one-click access to full logs.
frontend/: Vite + Vue 3 SPA handling OAuth login, YAML input, status polling, and firmware downloadsfunctions/: Cloudflare Pages Functions ([[path]].ts) implementing OAuth flow, session management, and GitHub Actions API proxy.github/workflows/esphome-compile.yml: GitHub Actions Workflow that performs the actual compilation.dev.vars.example: Example environment variables for local development; copy to.dev.vars
- Visit GitHub Settings → Developer settings → OAuth Apps to create a new OAuth App.
- Set Homepage / Callback URL to your future Cloudflare Pages domain, for example:
- Homepage:
https://your-project.pages.dev/ - Authorization callback URL:
https://your-project.pages.dev/auth/callback
- Homepage:
- Note the
Client IDand click "Generate a new client secret" to save theClient Secret. - Pages Functions will request
workflowandpublic_repo(orrepo) permissions to triggerworkflow_dispatchon public/private repositories.
- Create a Pages project in the Cloudflare dashboard (connect a Git repository or upload manually).
- Build settings example:
- Build Command:
npm install && npm run build --prefix frontend - Build Output Directory:
frontend/dist - Functions Directory:
functions
- Build Command:
- Add environment variables in Pages → Settings → Variables (Production & Preview):
GITHUB_CLIENT_IDGITHUB_CLIENT_SECRETSESSION_SECRET(random 32+ byte string, e.g.,openssl rand -base64 32)GITHUB_OAUTH_REDIRECT_URI(must match OAuth App callback; production uses Pages domain/auth/callback, development can usehttp://localhost:5173/auth/callback)GITHUB_REPO_OWNERGITHUB_REPO_NAMEGITHUB_WORKFLOW_ID(e.g.,esphome-compile.yml)GITHUB_WORKFLOW_REF(defaultmain)FRONTEND_URL(redirect URL after authorization; recommend Pages domain for production)ALLOWED_ORIGINS(comma-separated list of allowed CORS origins; must include Pages domain, addhttp://localhost:5173for development)GITHUB_REQUIRE_PRIVATE_REPO(default empty/false; set totrueonly when accessing private repos to requestreposcope)GITHUB_SERVICE_TOKEN(optional; platform default Fine-grained PAT; recommend selecting onlyworkflowandpublic_repopermissions)
Note: Cloudflare Pages stores variables separately for Production and Preview; you can use different OAuth Apps to distinguish environments.
- Install and run frontend:
cd frontend npm install npm run dev - Copy
.dev.vars.exampleto.dev.varsin the repository root and fill in your Dev OAuth App configuration. - Start Pages Functions local environment (requires
wranglerinstallation):If# In repository root wrangler pages dev frontend/dist --local --port 8787frontend/distdoesn't exist yet, runnpm run build --prefix frontendfirst. - Visit
http://localhost:5173in your browser; Vite will proxy/auth/*and/api/*requests tohttp://127.0.0.1:8787.
- (Optional) Click "GitHub Login" to authorize, granting
workflow+public_repo(orrepo) permissions; when not logged in, the platform usesGITHUB_SERVICE_TOKENto trigger Workflows. - Return to the page and paste your ESPHome YAML.
- If YAML contains
!secret, the system auto-detects and generates input fields with auto-completion for quoted values and local caching; confirm fields before submission. - If no custom archive password is set, the interface generates a 16-character alphanumeric password displayed for later use when extracting the artifact.
- After submission, the frontend Base64-encodes the YAML and triggers
workflow_dispatchvia Pages Functions (defaults to platform token; falls back to logged-in user token on failure). - Frontend polls Workflow status; upon completion, displays firmware download button to directly download the encrypted
firmware-<request_id>-password.zip. - Click "Logout" to clear session when switching accounts.
Page refresh doesn't lose YAML drafts or ongoing compilations; requests automatically recover and continue polling status.
- Decodes YAML to
config.yaml. - Installs ESPHome based on the version number passed from frontend (defaults to latest stable) and runs
esphome compile config.yaml. - Encrypts and packages all generated firmware
*.bin(and manifest) withconfig.yamlintofirmware-<request_id>-password.zip, uploaded toartifact/directory; artifacts retained for 1 day. - Run name includes
request_id; Pages Functions matches Workflow Run accordingly.
- OAuth Access Token stored in signed HttpOnly Cookie, accessible only to Pages Functions;
Secureflag automatically enabled in production. - Never commit real secrets to repository; configure production variables via Cloudflare dashboard, use
.dev.varsfor development (added to.gitignore). - To revoke authorization, remove the OAuth App in GitHub → Settings → Applications.
- When using
GITHUB_REQUIRE_PRIVATE_REPO=true, authorization scope expands torepo; ensure only enabled when necessary. GITHUB_SERVICE_TOKENshould be a Fine-grained PAT saved as Pages Secret; GitHub API quota per token is 5000 requests/hour; prompt users to login and switch to personal authorization when needed.