Pikbase Docs
Open console (opens the console)
Esc

Type to search.

Shipping and operations

CI/CD, deployment, and seeds

Automate tenant delivery, promote query-selected data and backend assets, and preserve or overwrite target edits.

Use the GSB CLI for repeatable tenant operations and resource packs for promoting selected backend resources and data. Keep release content, target-specific approval, and deployment results separate.

See Backend source control with Git for committing schemas, workflows, functions, libraries, and templates alongside application code.

Available capabilities and boundaries

Capability Available surface
Resolve CI configuration gsb config --json
Inspect local payloads against sync baselines gsb status --json; not a remote content comparison
Read or mutate registered tool contracts gsb call <tool> --json --input-file <path>; mutations require --yes
Upload changed checked-out assets gsb push --all-changed, with --dry-run for a preview
Execute and follow a workflow gsb run, including --json, --sync, and --attach
Batch supported entity operations gsb bulk, with --raw for unwrapped JSON
Seed assistant configurations gsb assistant seed <manifest>
Build/install a resource pack Application Service APIs and the existing pack actions
Inspect asynchronous tasks gsb task status <jobId>

addResourcePack and installResourcePack are API operations, not currently registered gsb call tools. Do not infer CLI availability from the API reference. Use gsb tools to inspect the installed tool catalog. There is no general gsb seed command. status → diff → plan → apply → verify is the accepted delivery direction, not a fully shipped sequence. Local gsb status exists, but does not provide remote three-way comparison. A push dry run is not an immutable approved plan.

pnpm gsb:sync refreshes managed repository files; it does not deploy tenant resources.

CI configuration and output

Pin @gsb-core/cli in the consuming repository's lockfile, install with pnpm install --frozen-lockfile, and use Node.js 20 or newer. In the Core monorepo, build the CLI and its workspace dependencies before invoking the binary. For parsed output, use pnpm exec gsb, not a package script that prints its own banner.

Provide GSB_TOKEN, GSB_TENANT_CODE, and GSB_BASE_URL from the CI environment. Store the token as an environment-scoped secret, never in source, command arguments, browser-prefixed variables, or retained deployment artifacts. Do not run interactive login in CI. Explicit environment credentials take precedence over saved credentials; conflicting selectors or aliases fail. Avoid inheriting another tenant's variables.

pnpm exec gsb config --json
pnpm exec gsb call query --json --input-file release/verification-query.json

The request file must contain a reviewed query against a real definition in the target tenant. config --json now reports resolved configuration and backend-verified identity. gsb verify-token also exposes token verification. Neither a hostname nor an unverified decoded JWT is sufficient authority for a mutation; resource permissions must still be enforced by the backend for each operation.

Migrated config and call commands emit successful envelopes to stdout and errors to stderr. call can also emit progress to stderr; do not parse the entire stderr stream as one JSON object. Use the exit status, then inspect ok, data, and the operation-specific result. An outer ok: true means the CLI invocation returned; it does not prove an asynchronous job completed or an inner business result succeeded. Do not print or retain unrestricted entity responses: token redaction is not PII redaction. JSON flags and exit semantics are not yet uniform across legacy commands.

Automated delivery pipeline

Use these stages whether the runner is GitHub Actions, Azure Pipelines, or another CI:

  1. Validate without deployment credentials: lint, typecheck in no-emit mode, test, and review source changes. Untrusted pull requests must never receive tenant secrets.
  2. Select and build once: review the resource-pack template, explicit asset-family allowlist, and seed/query scope; build and retain the exact pack identity.
  3. Deploy to staging: apply the exact artifact through an authorized installer or an existing GSB deployment workflow; wait for terminal success and verify readback.
  4. Approve production: bind approval to the target, exact artifact, data scope, and skip/overwrite policy. Use protected environments and trusted branches.
  5. Promote without rebuilding: install the same pack into production, then verify definitions, references, workflows, functions, and selected data.
  6. Record the result: retain pack/file identity, source commit, selection policy, target, approval, job correlation, observed terminal state, and verification evidence. Restrict artifact access and retention; omit credentials and raw customer data.

A source commit alone does not identify pack content: packing reads the selected live source tenant. Verify that source resources match the reviewed commit and that the query-selected rows are the approved set. Record content hashes where available; version text alone is not integrity or approval evidence.

Serialize delivery per target. Do not cancel an in-flight production mutation when a newer commit arrives. CI concurrency protects that pipeline only, not writes from other clients. Strong remote preconditions and cross-client locks need backend support.

GitHub Actions job example

This example automatically runs a pre-existing, reviewed deployment workflow on a trusted main push. It is a consuming-project example, not a workflow installed by the CLI. Configure the staging environment with its three GSB variables/secrets and GSB_DEPLOY_WORKFLOW_ID, and ensure the lockfile already pins the published CLI. The GSB workflow must own the real deployment contract and any idempotency checks; this example does not create an installer or build/select a resource pack.

name: GSB staging delivery
on:
  push:
    branches: [main]
  workflow_dispatch:
permissions:
  contents: read
concurrency:
  group: gsb-staging-delivery
  cancel-in-progress: false
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: staging
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        with:
          version: 9.15.0
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - name: Run the approved tenant workflow
        env:
          GSB_TOKEN: ${{ secrets.GSB_TOKEN }}
          GSB_TENANT_CODE: ${{ vars.GSB_TENANT_CODE }}
          GSB_BASE_URL: ${{ vars.GSB_BASE_URL }}
          GSB_DEPLOY_WORKFLOW_ID: ${{ vars.GSB_DEPLOY_WORKFLOW_ID }}
        run: |
          test -n "$GSB_TOKEN"
          test -n "$GSB_TENANT_CODE"
          test -n "$GSB_BASE_URL"
          test -n "$GSB_DEPLOY_WORKFLOW_ID"
          pnpm exec gsb config --json
          pnpm exec gsb run "$GSB_DEPLOY_WORKFLOW_ID" --sync --json --timeout 900 > "$RUNNER_TEMP/gsb-run.json"

Gate this job on your project's validation jobs. Pin third-party actions to reviewed commit SHAs according to repository policy. Environment secrets are limited to the deployment step, not dependency installation. Keep workflow output private; inspect its documented result and execute target-specific post-deployment queries before declaring the release healthy. Configure a separate protected production job with reviewers and the retained exact pack identity; do not rebuild from dev in that job. Never enable privileged deployment using untrusted checkout code or pull_request_target.

gsb run exits nonzero for observed Error/Cancelled states, but a timeout, waiting human task, or nonterminal result is not success. A timeout does not roll back or necessarily cancel server work. Inspect the existing instance with --attach or the existing task before retrying; restarting a workflow can duplicate side effects.

Resource packs: schema, logic, and data

Layer Selection responsibility
Tenant checkout Editable source; never copy credentials or another tenant's sync baseline
GsbResourcePackTmpl modules, apps, dataDefinitions, and dataQueries define scope
Build request moduleFields selects module-owned asset families at build time
Built GsbResourcePack Exact artifact selected by packId for staging and production
Target review/plan Conflicts, dependencies, data impact, and installation policy

Build through POST /api/app/addResourcePack using an existing authorized template:

{
  "note": "Approved catalog schema, logic, and reference-data release",
  "version": "1.2.0",
  "templateId": "reviewed-template-id",
  "moduleFields": [
    "entityDefs",
    "propertyDefs",
    "enums",
    "workflows",
    "functions",
    "codeLibraries",
    "docTemplates",
    "permissions",
    "roles"
  ]
}

moduleFields is a request option, not a template property. Omission includes every supported module family; [] includes none. A data-only template can select data without selecting module assets, provided the target already has the required schema. Always make module selection explicit. Add related libraries, enums, permissions, and other dependencies deliberately; do not assume omitted resources will appear.

Select only part of the source data

Resource packs are not limited to schema and code. Templates can select data by definition using dataDefinitions, or select a subset through saved dataQueries. For example, promote only reviewed catalog items in one release batch rather than every catalog record. Configure the saved query in the source tenant and associate its reference with the template; do not add an invented inline query field to the build request.

Use a query with explicit release predicates, such as an approved flag and a fixed release-batch key, against fields that actually exist in your schema. Preview it under the builder's permissions, verify the complete row set and dependencies, and capture counts and permitted-field expectations before packing. Avoid time-relative filters and uncontrolled pagination. The backend determines query serialization and related-row inclusion; verify built content instead of assuming a join exports all referenced rows or that a UI column projection excludes sensitive fields from a pack.

  • Do not also select the same whole definition through dataDefinitions when the release must contain only query-selected rows; broader selection can defeat the filter.
  • moduleFields: ["userQueries"] ships saved-query resources. Template dataQueries selects data using queries. These are different responsibilities.
  • Canonical starter editions deliberately restrict seeds and keep dataQueries empty. That policy does not prohibit selective queries in other resource-pack templates.
  • Exclude credentials, sessions, PII, development users, test orders, and unrelated operational data. Sensitive seed artifacts require restricted storage and review.
  • Resolve dependencies and identities in the target. Do not blindly copy source IDs, regenerate every ID, or assume a folder copy provides cross-tenant identity mapping.
  • Verify selected rows arrived and nonselected rows were not changed. Installation is not continuous replication; absence from a pack is not an instruction to delete.

Preserve user edits or overwrite

Install through POST /api/app/installResourcePack with an explicit policy:

{
  "packId": "approved-built-pack-id",
  "sourceTenant": "dev1",
  "tenantCode": "production-tenant",
  "runAsync": true,
  "skipUserModified": true
}
User choice skipUserModified Effect
Preserve target customizations true Ask the installer to skip resources it recognizes as user-modified
Overwrite target customizations false Allow the installer to apply packaged changes despite target edits

The UI's Overwrite My Changes choice is the inverse of skipUserModified. Use preserve as the normal update policy and require explicit approval for overwrite. This policy matters for schema definitions, columns/properties, workflows, functions, and other packaged resources; exact family and nested-property behavior is governed by the backend installer. The request exposes one installation-level boolean, not per-column switches. Verify preservation/overwrite with edited schema and property fixtures in an isolated tenant before depending on that granularity in production.

Overwrite is not permission to delete absent columns or rows and does not imply a transaction, full replacement, or universal rollback. Preserve can leave a target different from the pack, so report skips and verify dependencies rather than claiming an exact match. Do not automatically rerun a preserve installation with overwrite when verification finds a conflict. Review a separate installation and its scope.

Select exactly one of packId, templateId, or templateName. Template selectors resolve the latest pack and are unsuitable for promoting a previously approved build. Both source and target access must be authorized by GSB; request fields are not authority. Pack metadata alone does not provide an immutable hash/approval ledger.

For asynchronous installation, retain jobId and poll the owning tenant's POST /api/task/getJobStatus with bounded backoff. Succeeded permits readback verification; Failed or Deleted fails delivery. On timeout, inspect the same job instead of submitting a duplicate installation. Task acceptance is not completion.

Seed systems and data migrations

Need Recommended mechanism
Shared languages, currencies, reference catalogs Versioned resource pack with explicit definition/query data selection
A reviewed subset of business configuration Query-selected data pack with target readback
A small reviewed set of entity writes gsb bulk save through the existing Entity Service contract
Assistant configuration gsb assistant seed <manifest>; keep model/provider credentials separate
Backfill or transformation of existing target data Explicit reviewed GSB workflow/function, not an inferred pack merge
pnpm exec gsb bulk save --input-file release/reference-data.json --chunk-size 100 --stop-on-error --yes --raw
pnpm exec gsb assistant seed release/assistant-manifest.json

Supply real reviewed files before running these examples. Bulk's input is an array of tool inputs, for example { "request": { "entDefName": "YourDefinition", "entity": { ... } } } per item, not simply an array of entity rows. It returns per-item results and a nonzero exit when a call fails. --stop-on-error stops after a failing chunk; it does not undo earlier writes or stop other calls already submitted.

Seeds must be repeatable: use backend-supported stable identities or a unique business-key lookup that resolves the target ID before saving. Saving rows without identity can create duplicates. Do not assume a natural-key upsert, pack install, or workflow run is idempotent unless the backend contract proves it. Avoid blanket delete-and-reseed in production. Test a second application and verify that counts, identities, relationships, and user customizations remain correct.

Apply prerequisite schemas before data, preserve required references, and sequence data transformations explicitly. A type conversion or required-field addition may need a backfill before enforcement. Record migration completion and recovery evidence; choose forward repair or an explicitly approved entity-version/backup restore as appropriate. Full tenant backups are not a routine per-deployment action.

Release acceptance checklist

  • Exact artifact, source selection, target, and overwrite policy were reviewed.
  • Schema/code and the query-selected data match the approved source state.
  • Target identities and dependencies resolve without ambiguous matching.
  • Edited schemas/properties and nonselected rows behave as the chosen policy requires.
  • Build/install jobs reached terminal success and target readback passed.
  • Reapplication and partial-failure recovery were exercised in an isolated tenant.
  • The release record excludes credentials and retains only permitted evidence.

CLI-managed resources use immutable plans, per-resource lastUpdateDate claims, partial-application reports, and read-back verification. Resource-pack installation has separate backend behavior and must not inherit those guarantees by assumption. Tenant-wide deployment locks and backend migration ledgers still require real backend contracts; neither a CI job nor a client-side plan can manufacture them.

Contract sourcedocs/guides/cli-delivery-and-resource-packs.md