diff --git a/README.md b/README.md index ab1fa06..f269c51 100644 --- a/README.md +++ b/README.md @@ -17,17 +17,21 @@ Hosts Virtuals' internal apps on Google Cloud Run, so anyone who builds a tool ([`plugin/`](plugin), see "The Claude plugin") does this, and adds the files from [`templates/app/`](templates/app). The bizops portal's **Tech requests → Build an app** page walks a builder through it. -2. **Host it.** Use the **Host an app** form in the bizops portal. It runs +2. **Get a repo, with its secrets.** When the app is ready, the platform team creates a + private repo in `Virtual-Protocol`, adds the builder (who pushes the code), and adds + its secrets (Settings > Secrets and variables > Actions), named as in its + `.env.example`. Only repo admins can set secrets, so the builder sends the values + through a password manager share. Public values (`NEXT_PUBLIC_*`, `VITE_*`) go under + Variables instead. +3. **Host it.** Use the **Host an app** form in the bizops portal. It runs [`host-app.yml`](.github/workflows/host-app.yml), which checks the request and creates the app's Cloud Run service, its own service account and, if asked for, a storage bucket. Until its first deploy, the app's address shows a page ([`placeholder/`](placeholder)) listing what's left to do, with links. -3. **Add its secrets** in the app repo's GitHub settings (Settings > Secrets and - variables > Actions), using the names in its `.env.example`. Public values - (`NEXT_PUBLIC_*`, `VITE_*`) go under Variables instead. -4. **Merge to `main`** (or run the repo's Deploy workflow). The app repo's +4. **Deploy:** run the repo's Deploy workflow, or merge to `main`. The app repo's `deploy.yml` calls [`deploy-app.yml`](.github/workflows/deploy-app.yml), which - builds the image, copies the secrets into Secret Manager and deploys. + builds the image, copies the secrets into Secret Manager and deploys. A deploy + before hosting fails ("isn't hosted yet"): hosting creates the app's place to run. ## What hosting checks diff --git a/placeholder/server.mjs b/placeholder/server.mjs index 80f636d..3c0cdd2 100644 --- a/placeholder/server.mjs +++ b/placeholder/server.mjs @@ -15,15 +15,15 @@ const variables = names(VARIABLES) const secretsStep = secrets.length ? `
  • -

    Add its secrets

    -

    The app needs these settings. On GitHub, add each one with New repository secret, using its real value:

    +

    Check its secrets are added

    +

    The app needs these settings on GitHub. Only the repo's admins can add them, so the platform team does: send them any missing values through a password manager share, never in chat or email.

    ${codes(secrets)} - Open the secrets page + Open the secrets page (admins) ${ variables.length ? `

    These are public, so they go under the Variables tab instead:

    ${codes(variables)} - Open the variables page` + Open the variables page (admins)` : "" }
  • ` diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json index 9b9fc78..5a19275 100644 --- a/plugin/.claude-plugin/plugin.json +++ b/plugin/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "virtuals-platform", "description": "How to build internal apps that host on the Virtuals platform (Google Cloud Run, through projects-autodeploy): rules, templates and a checker", - "version": "1.0.0", + "version": "1.1.0", "author": { "name": "Virtuals Protocol" }, "repository": "https://github.com/Virtual-Protocol/projects-autodeploy" } diff --git a/plugin/skills/internal-app/SKILL.md b/plugin/skills/internal-app/SKILL.md index a806ac7..b69178f 100644 --- a/plugin/skills/internal-app/SKILL.md +++ b/plugin/skills/internal-app/SKILL.md @@ -17,16 +17,19 @@ things only they can do (see "Hand-off"). ## How an app goes live -1. **The code** is in a **private** repo in the `Virtual-Protocol` GitHub organization. -2. **You add the platform files** (templates in `${CLAUDE_SKILL_DIR}/templates/`) and keep - the app to the rules below. `platform.yaml` names the person who will host it as `owner`. -3. **The owner hosts it** with **Tech requests → Host an app** in the bizops portal: - https://bizops-912665393140.asia-southeast1.run.app/apps. It checks the repo, creates the - app's address, and lists the secrets to add. -4. **The owner adds the secrets** in the repo on GitHub (Settings → Secrets and variables → - Actions), named as in `.env.example`. -5. **Deploy:** merge to `main`, or run the repo's Deploy workflow (Actions tab). It takes about - 3–5 minutes. After that, every merge to `main` deploys by itself. +1. **Build it in a folder on the builder's computer.** No repo is needed yet. You add the + platform files (templates in `${CLAUDE_SKILL_DIR}/templates/`) and keep the app to the + rules below. `platform.yaml` names the builder, who will host it, as `owner`. +2. **When it's ready, the platform team creates its repo**: private, in the + `Virtual-Protocol` GitHub organization, with the builder added. You push the code to it + (`main`). +3. **The platform team adds the secrets** to the repo (only repo admins can). The builder + sends them the values through a password manager share, never in chat or email. +4. **The builder hosts it** with **Tech requests → Host an app** in the bizops portal: + https://bizops-912665393140.asia-southeast1.run.app/apps. It checks the repo and creates + the app's place to run and its address, so it must come before the first deploy. +5. **Deploy:** run the repo's Deploy workflow (Actions tab), or merge to `main`. It takes + about 3–5 minutes. After that, every merge to `main` deploys by itself. ## The rules @@ -81,8 +84,9 @@ key, `GOOGLE_APPLICATION_CREDENTIALS`, or AWS keys. ### Settings and secrets - Every env var the code reads goes in `.env.example`. At each deploy, the platform copies - the repo's **GitHub Actions secrets** with those names into the running app. The owner adds - them in the repo: Settings → Secrets and variables → Actions → New repository secret. + the repo's **GitHub Actions secrets** with those names into the running app. Only repo + admins can set them, so the platform team adds them; the builder sends the values through a + password manager share. Never ask the user to paste a secret's value to you. - **GitHub is the one place to change them.** A value changed in Google Cloud is overwritten by the next deploy. After changing a secret, deploy again (Actions → Deploy → Run workflow). - **Browser-visible values** (`NEXT_PUBLIC_*`, `VITE_*`) are baked in when the app is built. @@ -148,10 +152,11 @@ take a few seconds. single dashes, starting with a letter. 2. Default stack, unless the user already has one: **Next.js (App Router) + TypeScript**, plus Postgres on Supabase if it needs a database. -3. Copy the templates in. Fill in `platform.yaml` (`owner` is the user's `@virtuals.io` - email), add the health route, write `.env.example`, and add the `CLAUDE.md` section and - `.claude/settings.json`. -4. Build the features within the rules above. +3. Work in a folder on the user's computer and `git init` it; the repo on GitHub comes when + it's ready to host. Copy the templates in. Fill in `platform.yaml` (`owner` is the user's + `@virtuals.io` email), add the health route, write `.env.example`, and add the `CLAUDE.md` + section and `.claude/settings.json`. +4. Build the features within the rules above, and run the app locally so the user can try it. ### Getting an existing app ready (including moving off Railway or Vercel) 1. Run the checker (below) and read every error and warning. @@ -183,15 +188,17 @@ app the way the Dockerfile does, and confirm the health check answers. Always end with a short **"What you need to do"** list in plain language, with only what applies: -1. **Merge** the changes into `main` on GitHub. -2. **First time only, host it:** in the bizops portal, open **Tech requests → Host an app** - (https://bizops-912665393140.asia-southeast1.run.app/apps) and enter this repo. It takes +1. **No repo yet?** "Ask the platform team for a repository for this app (its name, and your + GitHub username). Once they've added you, ask me to push the app to it." Otherwise: + **merge** the changes into `main` on GitHub. +2. **Secrets:** "Send the platform team these, through a password manager share (never chat or + email), so they can add them to the repo: `FOO` (what it is and where to get it), …". Never + show real values. +3. **First time only, host it:** in the bizops portal, open **Tech requests → Host an app** + (https://bizops-912665393140.asia-southeast1.run.app/apps) and enter the repo. It takes 2–3 minutes and gives the app's address. -3. **Secrets:** "In the repo on GitHub: Settings → Secrets and variables → Actions → New - repository secret, add: `FOO` (what it is and where to get it), …". Never show real values. - The app's address lists the same names until its first deploy. -4. **Deploy:** "Merge to `main`, or open Actions → Deploy → Run workflow. It's live about - 5 minutes later." After the first time, every merge deploys by itself. +4. **Deploy:** "Open Actions → Deploy → Run workflow in the repo, or merge to `main`. It's live + about 5 minutes later." After the first time, every merge deploys by itself. 5. **Needs the platform team:** a database, a public app, a schedule, a custom domain, or a migration that drops or renames data. 6. **Problems found:** a tracked `.env` file, secrets in code, or anything you couldn't fix.