Deploy & Release

renmy runtime deploys the exact payload
it validated.

The same tool that runs your tests in milliseconds now ships them. renmy deploy runs your local gates, validates the identical payload in Salesforce, then deploys it, in one command. renmy release splits validate from deploy with an immutable receipt, so what reaches production is byte-for-byte what passed.

"Tests pass" and "deploy succeeded" are different claims.

A standard Salesforce deploy validates whatever is in your worktree at the moment you press enter. The tests that passed ten minutes ago ran against a different revision. The validation that succeeded yesterday belonged to a different payload. Nothing connects the evidence to the deployment.

renmy deploy connects them. It snapshots the selected source into a content-addressed bundle first, and every subsequent stage (local validation, tests, coverage, the org's own check-only validation, the deploy itself) operates on that same bundle. The result is recorded in a receipt under .nimbus/releases/.

The ungated path stays available and stays explicit: renmy sf project deploy start is the raw Salesforce deploy, spelled the way Salesforce spells it. renmy adds no shorter ungated alias, so the shortest command is the safe one.

bash
# One command: gates, org validation, deploy
renmy deploy --target-org staging --source-dir force-app

# Production needs explicit confirmation
renmy deploy --target-org production \
  --manifest manifest/package.xml \
  --confirm-production

# Deploy selected metadata only
renmy deploy --target-org qa \
  --metadata ApexClass:AccountService \
  --metadata ApexClass:AccountServiceTest

# The intentionally ungated escape hatch —
# the raw Salesforce deploy, clearly spelled
renmy sf project deploy start \
  --target-org dev --source-dir force-app

What runs, in order

Every stage reads the same staged bundle. A failure at any stage stops the run with a distinct exit code (21 local gate, 22 Salesforce validation, 23 deploy) so CI can react precisely.

  1. snapshot

    Snapshot

    renmy runtime materializes the selected source into a content-addressed bundle. Every later gate reads this exact payload rather than a moving worktree.

  2. validate

    Local validation

    renmy validate compiles the bundled Apex and metadata against the same rules a check-only deploy enforces.

  3. gate

    Local gates

    Your configured test selection, coverage threshold, mutation threshold, and permission-seam policy, run locally in seconds.

  4. check

    Salesforce validation

    A real check-only validation of the same bytes in the target org. For production targets, the validated job is retained for quick deploy.

  5. deploy

    Deploy

    Runs only after everything above passes. Production targets require explicit confirmation. Every step lands in the receipt.

Receipts: validate, approve, deploy Pro

Real release processes put a human decision between validation and deployment. renmy release validate runs every gate plus a real Salesforce check-only validation and writes an immutable receipt: bundle digest, git revision, org fingerprint, gate results, the Salesforce validation job ID, and its exact quick-deploy expiry.

renmy release deploy ships only that receipt. Where Salesforce supports it, it reuses the validated org-side job via quick deploy, inside Salesforce's 10-day window, without retransmitting source. Otherwise it deploys the exact stored bundle. A receipt whose source changed, whose validation expired, or whose target org doesn't match is rejected. There is no override flag.

Receipts and bundles are portable artifacts: validate on one CI runner, hold for approval, deploy from another machine. That is the designed path.

bash
# CI job 1: gates + Salesforce validation → receipt
renmy release validate --release-profile production

# (approval happens here — a human, or your
#  platform's protected-environment gate)

# CI job 2: deploy exactly the validated payload
renmy release deploy \
  --receipt .nimbus/releases/rel_01J9.json \
  --release-profile production \
  --confirm-production

# The org's deploy queue, from your terminal
renmy release status            # stuck-Pending diagnosis
renmy release watch rel_01J9    # live progress
renmy release requeue rel_01J9  # resubmit validated bundle

Every sf command through renmy sf

renmy sf passes any command (core or plugin, current or future) through to Salesforce CLI unchanged. Arguments, working directory, interactive prompts, signals, and exit codes are preserved. renmy runtime does not parse or reinterpret this surface, so nothing Salesforce ships is ever missing or behind.

renmy toolchain sf manages the dependency itself: report which sf the machine resolves, install the official @salesforce/cli package, and pin an exact version in committed config so every CI runner provably reproduces the same toolchain.

One tool starts every Salesforce task: the local work where renmy runtime is fastest and the remote work where Salesforce is authoritative, with the seam between them made explicit.

bash
# Any sf command, unchanged
renmy sf org login web
renmy sf data query --query "SELECT Id FROM Account" \
  --target-org dev
renmy sf package version create --package core \
  --code-coverage

# Toolchain: inspect and pin the Salesforce CLI
renmy toolchain sf status --verbose
renmy toolchain sf install --version 2.143.6

# Or from the other side: renmy runtime as an sf plugin
sf plugins install @nimbus-solution/nimbus-sf-plugin
sf nimbus apex run test

In your pipeline and your editor

The same release runs on GitHub Actions, GitLab CI/CD, Azure DevOps or a plain shell runner. A pipeline runs validate in one job, carries the receipt and bundle as a pipeline artifact through your platform's environment approval, and deploys from a fresh runner. The receipt's own verification is the safety net for the hand-off.

Both editors ship a Releases view driven by the same engine: validate and deploy actions, a live stage timeline, release history recovered from disk after an IDE restart, and a production confirmation dialog showing the target org, source selection, destructive component count, receipt age, and bundle digest before the button enables. The only deploy button is the assured one.

See the release-in-CI reference for profiles, secrets, and the exit-code contract, and the VS Code page for the editor experience.

yaml
# GitHub Actions, condensed
validate:
  steps:
    - run: renmy toolchain sf install --version ${{ vars.SF_VERSION }}
    - run: renmy release validate --release-profile ci
    - uses: actions/upload-artifact@v4
      with: { name: release, path: .nimbus/releases/ }

deploy:
  needs: validate
  environment: production   # ← your human approval gate
  steps:
    - uses: actions/download-artifact@v4
      with: { name: release, path: .nimbus/releases/ }
    - run: |
        renmy release deploy \
          --receipt "$(ls .nimbus/releases/rel_*.json)" \
          --release-profile ci --confirm-production

Four rules

The safe default is never paywalled.

Gated renmy deploy is a Free command. If safety cost money while the ungated path was free, we would be pricing you onto the unsafe path.

Salesforce's confirmations are never weakened.

Destructive changes, --ignore-errors, and production targets keep every confirmation Salesforce itself enforces. renmy runtime adds gates; it never removes them.

A failed receipt check has no override flag.

If the source changed, the validation expired, the org is wrong, or the toolchain is incompatible, the deploy is rejected and you revalidate. There is deliberately no --force.

renmy test still needs no org.

Everything on this page is optional. renmy test, validate, and debug work with no Salesforce CLI, no network, and no org, exactly as before.

Common questions

Can renmy runtime deploy to a Salesforce org?

Yes. renmy deploy is a one-shot gated deployment: it snapshots your source into a content-addressed bundle, runs renmy runtime validation and your configured local test gates against that bundle, validates the same bytes in the target org with a real Salesforce check-only validation, and only then deploys. renmy release splits validation from deployment with an immutable receipt for approval workflows.

Does renmy runtime replace the Salesforce CLI?

No. It orchestrates above it. Salesforce CLI remains the platform adapter for auth, deploys, packaging, and data. renmy sf passes any current or future sf command through unchanged, with arguments, interactive prompts, and exit codes preserved, so you can start every Salesforce task with renmy without losing anything sf can do.

Does renmy runtime replace my packaging or release-promotion tooling?

No. renmy runtime is the evidence layer: it snapshots what a deploy contains, runs your gates, validates it in the org, and attests the result in a signed receipt. It does not manage package versions, dependency-ordered installs, scratch-org pools, or data seeding. That stays with the package and promotion tooling you already use. Point renmy release at the bundle your pipeline assembles and it adds the proof around the deploy, rather than replacing the pipeline that builds it.

What is a release receipt?

An immutable JSON record written by renmy release validate: the exact bundle digest, git revision, target-org fingerprint, gate results, Salesforce validation job ID, and its quick-deploy expiry. renmy release deploy verifies the receipt still matches (same org, same bytes, unexpired validation, compatible toolchain) and refuses to deploy on any drift. Receipts and bundles are portable CI artifacts: validate on one machine, approve, deploy from another.

How does quick deploy work with renmy runtime?

When renmy release validate runs a production-style check-only validation, Salesforce keeps the validated job quick-deployable for 10 days. The receipt records the job ID and the exact expiry, and renmy release deploy uses sf project deploy quick, which deploys the already-validated job without retransmitting source. If quick deploy is unavailable and policy permits, renmy deploys the exact stored bundle instead, not a freshly read checkout.

Is the gated deploy a paid feature?

No. renmy deploy (local gates plus Salesforce validation plus a local receipt) is Free, and so is renmy sf pass-through. Pro adds the release workflow around it: named release profiles, portable validate-approve-deploy receipts, release history, and the VS Code and IntelliJ release views. Team runs that workflow in CI.

The gated deploy is also the shortest command.

renmy deploy is Free. Receipts and profiles are Pro, and running the release workflow in CI is Team. Both are currently free with no card required.