Docs / Build Workflow

Publish

The publish lifecycle

Publishing a workspace is a four-step rhythm — read the local state, see what differs, validate, push. Run all of these from the workspace root (or any subdirectory inside it):

looky status     # confirm root, instance, billing, workspace, sync state
looky diff       # show local-vs-server file differences
looky validate   # run the validation gate
looky push       # publish content (only after validate is clean)

push runs the same validation gate as validate and refuses to publish if anything fails — validate is the way to run that gate without publishing.

Two push scopes — content vs settings

looky push targets one of two distinct surfaces, never both at once:

  • Default (content push) — publishes content/** + workspace.yml. Hard-gated by validation. Fails if your runtime configuration has not been deployed yet.
  • --settings (config push) — publishes runtime/** + secrets/**. Validates the source declarations, then writes. Use it on first setup, after rotating credentials, or whenever you change source declarations.

Typical first-time order:

looky push --settings   # deploy runtime/sources.runtime.yml + secrets/ first
looky push              # then the content

What validation checks

When you run looky validate or looky push:

  • Local pass. YAML parses, files referenced exist, IDs are unique, query uses the :: separator, dashboards reference real visualizations, exports reference real dashboards, cron expressions are valid, the chart block on every visualization passes its typed schema.
  • Server pass. Source aliases are reachable, every Malloy model compiles, every published visualization dry-runs cleanly against the configured data sources.

If any check fails, the command exits non-zero and prints the error code, the file path, and a human-readable message. Warnings do not block — they appear in the output and let the push proceed.

Validation flags

  • --strict — adds per-visualization live-source validation. On Postgres and MySQL, runs EXPLAIN against the live database (one round-trip per viz, with a statement timeout). On BigQuery, runs a query cost estimate (free, no scanned bytes). Catches dialect errors and missing permissions that the default fast pass cannot. Use it before a release; skip it for quick iteration.
looky validate --strict   # the strict gate without publishing
looky push --strict       # publish behind the strict gate

Push mirrors your local content state. The client is the source of truth for its content scope — files present on the server but absent locally are deleted as part of the push. Run looky diff first and make sure every deletion listed is one you intend.

Error code families

Validation errors and warnings are tagged with a stable code prefix. The prefix tells you which gate fired and which file family it concerns.

  • WS*** — workspace.yml issues (missing fields, invalid identifier shape, unknown billing account).
  • RT*** — runtime / source declarations (missing or unsupported source type, missing credentials_file, missing dsn for postgres, credentials file not found in secrets/). Mostly warnings.
  • MD*** — model file issues (missing source alias reference, file outside content/, unreadable file).
  • VZ*** — visualization YAML structure (missing id/title/type/query, malformed query reference, duplicate id).
  • VZ020, VZ021 — visualization typed-schema violations: a chart.* property that is not in the schema, a wrong type, an out-of-range value.
  • DB*** — dashboard YAML issues (missing fields, layout_mode not in fluid_grid / document, references to unknown visualizations).
  • EX*** — export YAML issues (cron format, unknown dashboard reference).
  • MR*** — runtime errors reported by the server. MR000 load failure, MR001 Malloy compile / parse error, MR002 field not defined, MR003 unknown source alias, MR004 schema introspection failed, MR005 query engine unreachable, MR006 query engine timed out, MR008 model file missing, MR009 precheck catch-all, MR010 source unreachable from probe.

What the push uploads

A successful content push publishes the validated file set and reports counts of created / updated / unchanged / deleted files. Disaster recovery is your responsibility — keep the workspace in git, or rely on the local .bk/<timestamp>/ snapshot that looky pull writes when it overwrites local files.

A successful settings push publishes runtime/sources.runtime.yml and the files in secrets/ referenced by it. Validation runs first; if it fails the push prints the issues and nothing is written.

Post-publish verification

  1. Run looky list visualizations and looky list dashboards — confirm what is actually published on the server.
  2. Open https://my.looky.studio and confirm dashboards render.
  3. Open at least one visualization detail page and confirm data shows up. Validation does not check that mapping field names match the query result; that only surfaces when the chart actually renders.
  4. If a dashboard renders blank or a chart shows "no rows", check the underlying model query in the visualization detail page — that's the most direct trace.

A successful push only means your files were accepted and published. It does not mean every chart renders correctly. Always confirm visually after every push.

Failure recovery playbook

  • Validation failed locally (WS / RT / MD / VZ / DB / EX). Read the error code and file path; fix the YAML; re-run looky validate.
  • Validation failed on the server pass (MR* or VZ020). The error mentions the model or visualization that triggered it. Open that file, fix the Malloy or chart spec, re-run looky validate. If the error is MR010 (source unreachable), confirm that looky push --settings ran successfully recently with current credentials. When the server reports any error, nothing in the workspace is changed.
  • Push went through but the dashboard is wrong on the live site. The files published correctly but a chart is failing to render. Check mapping field names, format keys, and the actual query output in the viz detail.
  • Need to undo a push. Restore the prior content from git or from the local .bk/<timestamp>/ directory looky pull wrote, then looky push again.