Skip to content

feat(web): create a new site from a template under New project - #7553

Open
guitavano wants to merge 1 commit into
mainfrom
guitavano/create-site-button
Open

guitavano wants to merge 1 commit into
mainfrom
guitavano/create-site-button

Conversation

@guitavano

@guitavano guitavano commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

What is this contribution about?

Adds "Create a new site" to New project. From the repository picker the user chooses a site template (Storefront → deco-sites/storefront-tanstack, Blog → deco-sites/blog-tanstack), then the connected GitHub account (user or org) that will own the site, then a name. Studio generates a private repository from the template through its GitHub App, links it, and opens it as a project (site-editor view), reusing the existing import path.

  • Tool REPOSITORY_CREATE_FROM_TEMPLATE ({ accountId, name, template }). The template is an id from a server-side allowlist (@decocms/shared/site-templates), so a caller can't generate from an arbitrary repo. The name must be a lower-case slug of at most 100 characters.
  • createRepoFromTemplate on the GitHub provider client:
    • Never adopts an existing repository: a name that already exists on GitHub returns an error.
    • Waits, best effort, for GitHub to finish copying the template before returning.
    • Explains a missing Administration permission. Installations that predate administration: write on deco-cms need an owner to accept it.
    • The creation token spans the installation, because the repository has no id yet to scope it to. It is used only for the generate call and the read-back, and never leaves the client.
  • Partial grants: when the account has only some repositories granted to Studio, the repository Studio just created is added to that grant (grantRepository, an idempotent jsonb append). GitHub automatically gives the App access to a repository it creates with an installation token, including under selected-repositories installations (docs). A grant already at GitHub's 500-repository token limit is refused before anything is created.
  • Rollout: new org flag site_create_enabled, off by default. deco.cx staff and local dev always see the option (same pattern as the control-plane views). It is product gating only; the tool still needs a servable GitHub account.

Out of scope, as a follow-up: hosting. The control-plane's POST /sites (Nicácio's SITE_CREATE) only creates repositories under deco-sites, and this flow lets the user pick their own org. Wiring hosting would need the control-plane REST to accept an existing repo (repo mode) and the deco-hosting App installed on the customer's org.

How did you verify your code works?

  • bun run verify (format, oxlint, knip, unit): 9635 pass. tsc is clean for api, web, shared and e2e.
  • Storage integration apps/api/src/storage/git-provider-accounts.integration.test.ts (real Postgres), 3/3:
    • an id is appended once and bumps the account version;
    • a whole-installation grant (NULL) is left untouched;
    • another org's account is never changed.
  • E2E packages/e2e/tests/create-site.spec.ts, 2/2 locally against the GitHub stub. It runs under the synthetic GitHub App config, next to github-connect.spec.ts.
    • The full UI flow: New Project → Create a new site → Storefront → account → name. Typed text is turned into a slug and an invalid slug keeps the button disabled. The generated repository carries the template's files, is linked and private, the partial grant gains exactly the new repository id, and the project is created as "Created from the Storefront template".
    • Wire contract: a duplicate name is refused without adopting the existing repo, non-slug and oversized names are refused, and a template outside the allowlist is refused.
  • Unit: packages/shared/src/site-templates.test.ts covers the schema and allowlist, including empty, oversized and invalid slugs.

Screenshots/Demonstration

Screenshots of the four steps (entry, template, account, name) to be attached; captured by the e2e spec (create-site-{entry,template,account,name}.png in the Playwright output).

How to Test

  1. As deco.cx staff or in local dev (or with site_create_enabled on for the org), with a GitHub account connected under Settings → Repositories.
  2. Click New Project → Create a new site → pick Storefront → pick the GitHub account → type a name → Create site.
  3. Expected: a private <account>/<name> repository generated from deco-sites/storefront-tanstack, and the project opens on it.
  4. Retry with the same name. Expected: "already exists on GitHub. Choose another name."

Migration Notes

No database migration. New org flag site_create_enabled (off by default). To open the feature to a customer org, turn it on in the admin flags editor.

Review Checklist

  • PR title is clear and descriptive
  • Changes are tested and working
  • Documentation is updated (if needed)
  • No breaking changes

🤖 Generated with Claude Code

"Create a new site" in the repository picker: choose a site template
(storefront or blog), the connected GitHub account that owns it, and a
name. Studio generates a private repository from the template through its
GitHub App, links it, and opens it as a project.

- REPOSITORY_CREATE_FROM_TEMPLATE tool; template allowlist in
  @decocms/shared/site-templates
- GitHub client createRepoFromTemplate: never adopts an existing repo,
  waits for the template copy, explains missing Administration permission
- a partial installation grant gains the repository Studio created
- gated by the default-off org flag site_create_enabled (staff/local
  always)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the claude PR authored by a coding agent label Sep 25, 2026

This branch has not been deployed

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

Labels

claude PR authored by a coding agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant