---
name: deploy install-script
description: Build and deploy the creft.run install endpoint to Cloudflare Workers
tags:
  - deploy
  - cloudflare
---

```docs
## What this does

Builds the Cloudflare Worker from the template and deploys it via wrangler.

**Two steps:**
1. Bash block: reads `scripts/install.sh` and `cloudflare/workers/creft-run.js`, generates
   `cloudflare/workers/dist/creft-run.js` with the install script inlined as a JS template literal.
2. Node block: runs `npx wrangler deploy` in the `cloudflare/` directory, which reads
   `cloudflare/wrangler.jsonc` and uploads the generated worker to Cloudflare.

## Requirements

- `CLOUDFLARE_API_TOKEN` — Workers Scripts:Edit permission
- `CLOUDFLARE_ACCOUNT_ID` — your Cloudflare account ID

Both are read by wrangler from the environment automatically.

## Dry run

`creft deploy install-script --dry-run` shows the rendered blocks without executing them.
The generated JS is not written and nothing is deployed.

## After deployment

`curl -fsSL creft.run` returns the current contents of `scripts/install.sh`.
`curl -fsSL creft.run/v0.3.0 | sh` installs v0.3.0 exactly.
```

```bash
set -eu

REPO_ROOT="$(git rev-parse --show-toplevel)"
SCRIPT_FILE="$REPO_ROOT/scripts/install.sh"
TEMPLATE_FILE="$REPO_ROOT/cloudflare/workers/creft-run.js"
DIST_DIR="$REPO_ROOT/cloudflare/workers/dist"

[ -f "$SCRIPT_FILE" ]   || { printf 'error: %s not found\n' "$SCRIPT_FILE" >&2;   exit 1; }
[ -f "$TEMPLATE_FILE" ] || { printf 'error: %s not found\n' "$TEMPLATE_FILE" >&2; exit 1; }

mkdir -p "$DIST_DIR"
GENERATED_JS="$DIST_DIR/creft-run.js"

# Write generated header with timestamp and source hash
SCRIPT_HASH="$(shasum -a 256 "$SCRIPT_FILE" | cut -d' ' -f1)"
TIMESTAMP="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
printf '// Generated by creft deploy install-script at %s\n// Source: scripts/install.sh (sha256: %s)\n\n' \
  "$TIMESTAMP" "$SCRIPT_HASH" > "$GENERATED_JS"

# Write template prefix — everything before the marker line
sed -n '/^\/\/ __INSTALL_SCRIPT_CONTENT__$/q;p' "$TEMPLATE_FILE" >> "$GENERATED_JS"

# Escape install script for JS template literal: backslashes, backticks, ${}
sed 's/\\/\\\\/g; s/`/\\`/g; s/\${/\\${/g' "$SCRIPT_FILE" >> "$GENERATED_JS"

# Write template suffix — everything after the marker line
sed -n '/^\/\/ __INSTALL_SCRIPT_CONTENT__$/,$ { /^\/\/ __INSTALL_SCRIPT_CONTENT__$/d; p; }' "$TEMPLATE_FILE" >> "$GENERATED_JS"

printf 'Built worker: %s (%s bytes from %s)\n' \
  "$GENERATED_JS" \
  "$(wc -c < "$GENERATED_JS" | tr -d ' ')" \
  "$SCRIPT_FILE"
```

```node
// deps: wrangler
const { execSync } = require("child_process");
const path = require("path");

const repoRoot = execSync("git rev-parse --show-toplevel", { encoding: "utf8" }).trim();
const cfDir = path.join(repoRoot, "cloudflare");

execSync("npx wrangler deploy", {
  cwd: cfDir,
  stdio: "inherit",
  env: { ...process.env },
});
```
