Continuous Integration

Automation & CI

Continuous Integration

Run validation, drift review, secret scanning, and application tests in CI with explicit flags, structured output, and narrowly scoped credentials.

CI principles

  • Pass all selections as flags; CI has no interactive prompt session.
  • Prefer --json, --format github, or --sarif over parsing human output.
  • Use one scoped automation credential per trust boundary.
  • Do not enable --show-values or echo GHOSTABLE_CI_TOKEN.
  • Keep production credentials out of untrusted pull-request jobs.

Create CI access

From an owner device:

CI credential
$ ghostable access create --name github-actions --kind ci --grant staging:reader
 

Store the returned token in the CI platform as GHOSTABLE_CI_TOKEN and commit the generated public device, policy, and access-grant changes. A reader grant is sufficient for validation, review, and test-time decryption.

Validation and review

CI checks
$ ghostable validate --env staging --json
$ ghostable review --base origin/main --head HEAD --format github
$ ghostable hygiene report --env staging --sarif
 

Pass an explicit base in CI so comparisons do not depend on checkout tracking configuration. Validation, review, and scan exit non-zero when actionable findings remain. Hygiene reports findings in its payload but exits successfully unless execution itself fails, so enforce hygiene thresholds through the SARIF consumer or a separate policy step.

Run tests with values

Inject values into the test process without writing a persistent env file:

Test with injected values
$ ghostable env run --env staging --no-inherit --mask-output --strict -- npm test
 

--no-inherit reduces ambient runner variables, --mask-output replaces exact injected values found in child stdout and stderr, and --strict fails when requested configuration is missing or invalid. Masking is best effort: encoded, transformed, split, or file-written values can still escape. The runner can access decrypted process memory, so use an isolated CI environment.

Pull-request safety

Run repository-only secret scanning without credentials on untrusted changes, and reserve decryption for protected branches or reviewed deployment jobs.

Automation contract

stdout
Automation-oriented output is written here when --json, --format github, or --sarif is supported and selected.
stderr
Usage, verification, runtime, and final failure messages are written here. A failing JSON command may still emit a complete JSON result on stdout.
Exit 0
The command completed and its checks passed.
Exit 1
Invalid usage, a runtime or verification error, or findings from commands that fail checks such as validate, review, and scan. Hygiene reports findings without failing by default.
Exit 130
An interactive prompt was canceled.
env run
Returns the child process exit code when that process starts and exits unsuccessfully.

Structured formats are available only when the command's --help lists them. Version-lock the CLI, ignore unknown JSON fields, and never assume structured output is secret-free: credential creation intentionally returns its token, while value-reading commands remain redacted unless plaintext output is explicitly requested.

See the command reference automation contract for the supported formats and a validation payload example.

Example pipeline

This GitHub Actions workflow scans pull requests without a credential and limits decryption to pushes on the protected main branch. Store GHOSTABLE_CI_TOKEN as a repository or environment secret available only to the protected job.

name: Ghostable

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  scan-untrusted:
    if: ${{ github.event_name == 'pull_request' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npx ghostable review --base "origin/${{ github.base_ref }}" --head HEAD --secrets-only --format github

  protected-checks:
    if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
    runs-on: ubuntu-latest
    env:
      GHOSTABLE_CI_TOKEN: ${{ secrets.GHOSTABLE_CI_TOKEN }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npx ghostable validate --env staging --json
      - run: npx ghostable review --base "${{ github.event.before }}" --head "${{ github.sha }}" --format github
      - run: npx ghostable env run --env staging --no-inherit --mask-output --strict -- npm test

Pin @ghostable/cli and commit the lockfile so CI and developers execute the same 3.x release.

CLI 3.x introduction Documentation
Installation Documentation
Start a new project Getting Started
Adopt an existing project Getting Started
Onboard a team member Getting Started
Repository and storage Core Concepts
Environments Core Concepts
Variables and promotions Core Concepts
Access and devices Core Concepts
Daily development workflow Workflows
Review and secret scanning Workflows
Hygiene and rotation Workflows
Automation credentials Automation & CI
Continuous integration Automation & CI
Deployments Automation & CI
Validation Reference
Command reference Reference
Configuration Reference
Security Reference
Backups & Offline Reference
Agent integration Reference
Troubleshooting Reference
Ghostable Desktop overview Desktop
Installation Desktop
Projects and setup Desktop
Interface tour Desktop
Environments and variables Desktop
Local environment files Desktop
Validation and review Desktop
Activity Desktop
Access and automation Desktop
Project settings Desktop
Application settings Desktop
Licensing and updates Desktop
Security and storage Desktop
Troubleshooting Desktop
No results found