Public
Like
min-github-app
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
githubApp.http.ts
https://min--3936819eb96511f092650224a6c84d84.web.val.run
This Val Town project exposes an HTTP webhook that acts as a lightweight GitHub App backend. It listens for repository creation events, verifies the webhook signature, infers the project type (Android vs. Node.js), synchronizes the required GitHub Actions secrets, and finally dispatches a bootstrap workflow in the new repository.
- Validates
POSTrequests signed withx-hub-signature-256usingGITHUB_APP_WEBHOOK_SECRET. - Confirms the repository was cloned from an approved template. If the template is unknown, it scores the repo tree for Android or Node.js indicators.
- Creates an installation-scoped Octokit client, normalizes the app private key (PKCS#1 → PKCS#8), and hydrates GitHub Actions secrets using the repo public key.
- Waits for
.github/workflows/bootstrap-action.ymlto register, enables it if necessary, and triggers a workflow dispatch on the default branch.
Set these secrets in the Val configuration before deploying:
| Variable | Description |
|---|---|
GITHUB_APP_WEBHOOK_SECRET | Shared secret used to validate incoming GitHub webhooks. |
GITHUB_APP_ID | Numeric GitHub App identifier. |
GITHUB_APP_PRIVATE_KEY | PEM string for the GitHub App private key (PKCS#1 or PKCS#8; literal newlines or \n escapes both work). |
ANDROID_ACTION_SECRET__* | One env var per secret. Name must start with ANDROID_ACTION_SECRET__ and continue with the GitHub secret key (e.g. ANDROID_ACTION_SECRET__ANDROID_KEYSTORE). |
NODE_ACTION_SECRET__* | One env var per secret. Name must start with NODE_ACTION_SECRET__ and continue with the GitHub secret key (e.g. NODE_ACTION_SECRET__NPM_TOKEN). |
Example env layout:
ANDROID_ACTION_SECRET__ANDROID_KEYSTORE=base64-keystore
ANDROID_ACTION_SECRET__ANDROID_KEYSTORE_PASSWORD=super-secret
NODE_ACTION_SECRET__NPM_TOKEN=ghs_...
When a repository is created from cmwen/min-node-app-template, the handler will upsert the NPM_TOKEN secret in that repo using NODE_ACTION_SECRET__NPM_TOKEN from Val's environment.
- Template Mapping – Known templates map directly to a project type:
- Android:
https://github.com/cmwen/min-android-app-template→android - Node.js:
https://github.com/cmwen/min-node-app-template→node
- Android:
- Repo Tree Heuristics – If the template is unknown, the handler fetches the git tree and counts indicator files:
- Android:
build.gradle,gradlew,AndroidManifest.xml, etc. - Node.js:
package.json,pnpm-lock.yaml,vite.config.ts, etc.
- Android:
- Fallback – When the score is inconclusive, type becomes
unknownand no secrets are synced.
- Pulls the repo public key via the Actions API.
- Encrypts each secret with Tweetsodium (
crypto_box_seal). - Upserts secrets using the installation token. Secret names missing the expected prefix still upload, but a warning is logged.
- Polls for
bootstrap-action.ymlregistration (up to ~60 seconds). - Enables the workflow if it is disabled.
- Dispatches the workflow once the repo is ready; otherwise responds with a 202 to allow retrying later.
- Add Templates: Update
TEMPLATE_TYPE_MAPwith new template URLs. - Add Heuristics: Extend
ANDROID_INDICATORS/NODE_INDICATORSor introduce new project types. - Add Secrets: Include additional key/value pairs in the JSON env vars. The handler will encrypt and upload everything it finds.
- Use
vt watchfor rapid iteration while sending signed webhook payloads (e.g., viacurl). - Inspect Val Town logs to confirm classification, secret sync status, and workflow dispatch attempts.
- If workflow dispatch fails with
404, ensure the workflow file exists on the default branch and that GitHub has finished initializing the repo (may take a minute on newly-created repositories).
