Workspaces, sites, and publishing

Choose the right context, create or inspect a site, then publish production safely.

Select a workspace

Workspace commands
ploy workspace list
ploy workspace use --id <workspace-id>
ploy workspace use
ploy workspace current
ploy --workspace <workspace-id> workspace current

workspace list automatically pages through every accessible, non-frozen workspace. workspace current prints the effective workspace and its source: flag, env, or stored.

Interactive selection requires a TTY. With --dry-run, workspace use requires an explicit --id.

Workspace resolution

  1. --workspace <id>
  2. PLOY_WORKSPACE_ID
  3. The workspace saved by ploy workspace use
  4. No workspace

Flags and environment variables do not change saved selection. Saving a different workspace clears the saved site.

Select a site

Site selection
ploy site list
ploy site use --id <site-id>
ploy site use

site list returns up to 100 sites in the effective workspace. site use saves a site but does not change the effective workspace; the site must belong to the saved current workspace.

Interactive selection requires a TTY. With --dry-run, site use requires --id.


ploy site init

Create a blank Astro site or import a publicly reachable site in the background.

Create or import a site
ploy site init [--name <title>] [--slurp <public-url>] [--wait] [--json]
OptionBehavior
--name <title>Set a title up to 200 characters. Ploy derives one when omitted.
--slurp <public-url>Import a public HTTP(S) site. Embedded URL credentials are rejected.
--waitPoll for up to 15 minutes and succeed only when the site is ready.
--jsonPrint machine-readable output; with --wait, print one final status object.

Any workspace member can create a blank Astro site. Importing with --slurp requires the workspace owner role. The command does not modify local files or select the new site. --dry-run is not supported.

JSON creation response
{
  "site": { "id": "<site-id>", "title": "My site" },
  "state": "pending",
  "dispatch": "accepted",
  "workflowId": "<workflow-id>"
}

dispatch and workflowId appear only for imports. If import dispatch cannot be confirmed, Ploy retains and prints the created site and workflow ID with state: "status-unavailable" and dispatch: "unconfirmed".

Do not rerun init after an uncertain dispatch. Inspect the retained site with ploy --workspace <workspace-id> site status --id <site-id>.

ploy site status

Read site readiness
ploy site status [--id <site-id>] [--json]

--id temporarily overrides the selected site without changing selection. Site state is pending, ready, failed, or status-unavailable.

Imported-site status
{
  "site": { "id": "<site-id>", "title": "My site" },
  "state": "pending",
  "stage": "cloning",
  "sandbox": { "status": "creating", "startupStep": "starting" },
  "clone": { "status": "running", "step": "crawl", "message": "…" }
}

Sandbox status is ok, creating, degraded, or failed. Blank sites omit the clone object.


ploy site publish

Publish production
ploy site publish [--wait] [--json]

The command always targets production. There is no target flag, staging mode, or unpublish command. A selected workspace and site are required.

Retries safely rejoin the same operation or an already-active publish for the site.

Accepted publish
{
  "operationId": "<operation-id>",
  "reused": false,
  "workflowStarted": true
}

A reused response also includes reuseReason: "operation_key" or "active_site".

Wait for production

With --wait, the CLI polls for up to nine minutes and retries throttles and transient edge failures. It exits 0 only when production reaches ready.

  • 1: production reached a terminal failure.
  • 4: polling timed out; the publish is still running.
  • 5: API contact was lost; the publish is still running.

With --json, every outcome prints exactly one JSON object on stdout containing operationId.

Preview a publish

Dry-run production publish
ploy --dry-run site publish
Dry-run response
{
  "dryRun": true,
  "target": "production",
  "workspaceId": "<workspace-id>",
  "siteId": "<site-id>"
}

ploy site publish-status

Read a publish operation
ploy site publish-status <operation-id> [--json]

The operation must belong to the selected workspace and site pair. Exit 0 means the read succeeded; inspect status and deployment rows to determine the publish outcome. --dry-run is not supported.

Publish operation
{
  "operationId": "<operation-id>",
  "status": "in_progress",
  "deployments": [
    {
      "target": "production",
      "status": "building",
      "currentStep": "Building site",
      "url": null,
      "error": null
    }
  ]
}

Operation status is in_progress, succeeded, or failed. Deployment status is queued, building, ready, error, or cancelled.


Code Sync

Code Sync commands use the site selected by ploy site use, require that site to belong to the effective workspace, and require a plan that includes Code Sync. They are human-readable only: no --json or --dry-run.

ploy site code-sync init

Initialize Code Sync
ploy site code-sync init

Ploy prepares the selected site's GitHub repository, creating it when needed, then prints connection status, setup links, and HTTPS and SSH clone commands.

Code Sync workflow
git clone https://github.com/<owner>/<repo>.git
cd <repo>
# make changes on main
git pull --rebase origin main
git push origin main
ploy site code-sync sync

ploy site code-sync sync

Import GitHub main into Ploy
ploy site code-sync sync

On success, the CLI prints the imported GitHub commit and resulting Ploy site-workspace commit. If changes conflict, resolve them in the editor and retry.


Keep going