Skip to content

CI: deploy template demos when a new template is merged - #43

Merged
deividasma merged 2 commits into
mainfrom
ci/deploy-template-demos-on-merge
Oct 19, 2026
Merged

deividasma merged 2 commits into
mainfrom
ci/deploy-template-demos-on-merge

Conversation

@deividasma

@deividasma deividasma commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

What

Merging a PR that adds a template now publishes its demo to https://<id>.hostingertemplates.com automatically. This replaces the manual Hostinger Connector step in skills/deploy-templates. (Slack thread)

When it deploys

How

Job Secrets Does
detect none Picks the templates to deploy
build (matrix) none npm ci and npm run build, then package-demo.mjs zips the result
deploy template-demos environment deploy-demos.mjs publishes the zips one at a time

package-demo.mjs decides the deploy type:

  • Static: no deploy.entryFile, and the build output has an index.html (deploy.outputDirectory, else dist, build or out). It zips that output.
  • Node.js app: everything else (Express, Fastify, Hono, Nest, Nuxt SSR). It zips the committed source with git archive, leaving out preview/, node_modules and build output. Hostinger runs npm ci and the build on the server.

deploy-demos.mjs uses the same public API endpoints as the Hostinger MCP deploy tools (@hostinger/mcp). For each template it:

  1. Finds the account username for hostingertemplates.com (exact domain match, never a subdomain).
  2. Creates the subdomain <id> with folder <id> if it doesn't exist, then waits until it's listed.
  3. Gets upload credentials, retrying because new subdomains briefly return 500.
  4. Uploads the zip in 10 MB chunks.
  5. Deploys it:
    • static: POST …/deploy
    • Node.js: GET …/nodejs/builds/settings/from-archive, merges the catalog deploy settings (appType, buildCommand, outputDirectory, entryFile), defaults to Node 22, starts the build, then polls until it completes. If it fails, the log tail is printed.
  6. Checks the live URL until it returns 200 and, for static sites, contains the built page's <title>. That skips Hostinger's browser-check page while DNS and TLS are still setting up.

Templates are deployed one at a time on purpose: parallel subdomain creation or upload-credential requests on one account fail with unfinished-action limits and 500s.

Security

  • Token location: HOSTINGER_API_TOKEN is stored only in the template-demos environment, and only main can deploy to it. There's no repo-level secret.
  • No PR triggers: the workflow never runs on pull_request or pull_request_target, so forks and PR code never get the token.
  • Template code never runs with the token: templates are installed and built in the secret-free build job. The deploy job only checks out .github/scripts and runs deploy-demos.mjs, which uses Node built-ins only.
  • Artifacts are checked: the deploy job only accepts template IDs that detect selected, so a tampered build artifact can't target another subdomain.

Catalog demoUrl

TEMPLATE_SCHEMA.md now asks for demoUrl: https://<id>.hostingertemplates.com in the PR that adds a template. Before, it stayed null until someone deployed by hand.

The alternative is a bot PR that writes demoUrl after deploying. main needs a review, so that would mean a second approval for every template. The cost of this choice: if a deploy fails, the catalog links to a dead demo until someone fixes it and reruns the workflow. A failed run turns red and lists the failure in the job summary.

deploy-templates skill

Its description told agents to use it "when publishing, deploying, or refreshing template demos". So Dex Code or Claude asked to create and publish a template would follow the manual connector steps. That duplicates the workflow, needs an interactive Hostinger sign-in that Dex Code jobs can't do, and its catalog step contradicts the new demoUrl rule. The skill (same file and name, 175 → 84 lines) is now a runbook:

  • Redeploy: run the workflow with gh workflow run … --ref main -f templates="…" and watch it.
  • Failed runs: what each failure looks like (build job, Hostinger Node.js build, live-check timeout, expired token), and that a merged fix needs a manual rerun.
  • Manual fallback: for moving to another hosting plan or when Actions is unavailable.

Testing

  • Packaging: ran locally on callout (Vite → static), couch-to-5k (SvelteKit, catalog outputDirectory → static), consultancy (Nuxt SSR → Node.js), api-reference (Nest → Node.js) and quickstart (Hono, entryFile → Node.js). Static zips have index.html at the root; source zips have no preview/, node_modules or build output.
  • Deploy script: ran end to end against a mocked API and upload server, covering:
    • new and existing subdomains
    • a transient 500 retry
    • catalog settings applied to Node.js builds
    • a failed build, with the log tail printed and exit 1
    • an artifact that wasn't selected, which is refused
    • a missing build artifact
    • a 25 MB zip uploaded in three chunks
    • a wrong token (401, exit 1)
  • Live check: confirmed against today's real demo at callout.hostingertemplates.com.
  • Workflow lint: actionlint is clean.
  • Not tested yet: the real Hostinger API. The first real call happens after merge.

After merge

  • Run Deploy template demos from the Actions tab with callout. It redeploys an existing demo with the same content, as a first real check of the upload, subdomain and live-URL steps.
  • template-demos environment created, limited to main, with HOSTINGER_API_TOKEN set.

🤖 Generated with Claude Code

Merging a PR that adds templates/<id>/package.json builds the template and
publishes it to https://<id>.hostingertemplates.com through the Hostinger
public API. Changes to existing templates (Dependabot security groups,
manual dependency bumps) do not deploy; existing demos can be redeployed
with workflow_dispatch.

The API token lives in the main-only `template-demos` environment and is
only exposed to the deploy job, which runs no template or npm code.
@github-actions

Copy link
Copy Markdown

Template preview

No templates/* package changed in this PR.

New templates deploy on merge, so the skill now covers redeploying through
the workflow, diagnosing failed runs, and a short manual fallback for plan
moves or when Actions is unavailable.
@deividasma
deividasma marked this pull request as ready for review October 19, 2026 05:54
@deividasma
deividasma merged commit 1d16a2f into main Oct 19, 2026
5 checks passed
@deividasma
deividasma deleted the ci/deploy-template-demos-on-merge branch October 19, 2026 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant