WendyOS Docs

Install Script Hosting

The public install one-liners are served from Google Cloud, not GitHub Pages:

Install Script Hosting

The public install one-liners are served from Google Cloud, not GitHub Pages:

curl -fsSL https://install.wendy.dev/cli.sh   | bash
curl -fsSL https://install.wendy.dev/agent.sh | bash

Why

install.wendy.dev was previously a GitHub Pages custom domain (deployed by the now-removed .github/workflows/static.yml). GitHub Pages soft-throttles a single IP and returns 403 when many people install at once from one network (e.g. a workshop behind one NAT). The scripts also resolved their version from the GitHub REST API (60 requests/hour per IP), which failed the same way. Both are now served from GCS.

What is hosted

ObjectServed atContent-Type
agent.shhttps://install.wendy.dev/agent.shtext/x-shellscript
cli.shhttps://install.wendy.dev/cli.shtext/x-shellscript
manifest.jsonhttps://install.wendy.dev/manifest.jsonapplication/json

manifest.json carries { "latest": "<version>", "latest_nightly": "<version>" }. The scripts read latest to resolve the install version and fall back to the GitHub API only if the manifest is unreachable.

Publishing

The publish-install-scripts job in .github/workflows/build.yml uploads the two scripts and merges the channel pointer into manifest.json on every main push and on stable release, using .github/scripts/publish-install-scripts.sh. It authenticates with the same Workload Identity Federation identity as the docs and agent-mirror publishers.

Objects are uploaded with Cache-Control: public, max-age=300, so changes take effect within about five minutes.

Infrastructure

Static files live in the public bucket wendy-install-public and are served through the same global external HTTP(S) load balancer that fronts docs.wendy.dev (see docs-site.md). The load balancer terminates HTTPS; a host rule routes install.wendy.dev to a backend bucket for wendy-install-public.

One-time maintainer runbook (LB + cert + DNS)

Provision before merge: the bucket and its IAM bindings (step 1 below) must exist BEFORE this branch merges to main — the publish-install-scripts job runs on every main push and will fail if the bucket or write IAM isn't in place yet.

Run these once, from a shell authenticated to the Wendy GCP project. Replace <PROJECT> with the project id, <URL_MAP> / <TARGET_PROXY> / <CERT> with the existing docs load-balancer resource names (find them with gcloud compute url-maps list, gcloud compute target-https-proxies list, gcloud compute ssl-certificates list).

# 1. Create the public bucket and make its objects world-readable.
gcloud storage buckets create gs://wendy-install-public \
  --project=<PROJECT> --location=us --uniform-bucket-level-access
gcloud storage buckets add-iam-policy-binding gs://wendy-install-public \
  --member=allUsers --role=roles/storage.objectViewer

# Grant the CI/WIF deploy service account (vars.GCP_SERVICE_ACCOUNT) write access
# so the publish-install-scripts job can upload objects and update the manifest.
gcloud storage buckets add-iam-policy-binding gs://wendy-install-public \
  --member=serviceAccount:<SERVICE_ACCOUNT> --role=roles/storage.objectAdmin

# 2. Seed the bucket so the LB has objects to serve before DNS cutover.
#    (CI republishes these on every build; this is just for verification.)
gcloud storage cp go/internal/cli/assets/docs/agent.sh gs://wendy-install-public/agent.sh \
  --content-type=text/x-shellscript --cache-control="public, max-age=300"
gcloud storage cp go/internal/cli/assets/docs/cli.sh gs://wendy-install-public/cli.sh \
  --content-type=text/x-shellscript --cache-control="public, max-age=300"

# 3. Back the bucket with a backend bucket and add a host rule to the docs LB.
gcloud compute backend-buckets create wendy-install-backend \
  --gcs-bucket-name=wendy-install-public --enable-cdn --project=<PROJECT>
gcloud compute url-maps add-path-matcher <URL_MAP> \
  --path-matcher-name=install \
  --default-backend-bucket=wendy-install-backend \
  --new-hosts=install.wendy.dev \
  --global \
  --project=<PROJECT>

# 4. Add install.wendy.dev to a Google-managed certificate and attach it.
#    Managed certs take minutes-to-tens-of-minutes to become ACTIVE.
gcloud compute ssl-certificates create wendy-install-cert \
  --domains=install.wendy.dev --global --project=<PROJECT>
gcloud compute target-https-proxies update <TARGET_PROXY> \
  --ssl-certificates=<CERT>,wendy-install-cert --global --project=<PROJECT>

# 5. Find the LB's global anycast IP.
gcloud compute forwarding-rules list --global --project=<PROJECT>

Then, in the DNS zone for wendy.dev:

  • Remove the existing install.wendy.dev record pointing at GitHub Pages (CNAME -> wendylabsinc.github.io) and the GitHub Pages custom-domain binding in the repository's Pages settings.
  • Add install.wendy.dev A (and AAAA if the LB has IPv6) records → the load balancer's global IP from step 5.

Verify before announcing:

curl -fsSL https://install.wendy.dev/manifest.json
curl -fsSL https://install.wendy.dev/agent.sh | head -1   # -> #!/usr/bin/env bash

After cutover

Once install.wendy.dev resolves to the load balancer, flip the publish-install-scripts job's "Verify scripts are reachable" step in .github/workflows/build.yml from https://storage.googleapis.com/wendy-install-public/<name> back to https://install.wendy.dev/<name> (a comment in that step already flags this).

On this page