This is a data repo of Acumatica ERP configuration-as-code YAML. The sample config is Lab5 Gateway Works: a single-branch USD manufacturer that assembles IoT gateway kits (3 kits, 9 parts, 6 vendors, 7 customers).
The acu CLI lives elsewhere:
- Source and docs: https://github.com/kborovik/acumatica-cli
- Install from PyPI: https://pypi.org/project/acumatica-cli/
This repo holds YAML seeds (bootstrap/, baseline/, setup/, scenario/) plus the Bootstrap endpoint contract at bootstrap/project.xml (packaged by acu bootstrap / acu tenant create).
target.yaml records the verified ERP build and Default API generation.
Credentials stay local; never commit a plaintext .env.
The sample was verified against Acumatica ERP 26.101.0225 and Default API 25.200.001 (see target.yaml).
Bootstrap endpoint version comes from bootstrap/project.xml.
Dual-served seeds use symbolic endpoint: bootstrap or endpoint: default (acu v0.10+).
The target tenant must be brand new and empty. Do not run this sample against a tenant that already has company setup, features, or master data. A clean tenant is the only supported starting point for full apply.
git clone https://github.com/kborovik/acumatica-gitops.git
cd acumatica-gitopsuv tool install acumatica-clilater: uv tool install acumatica-cli --upgrade
Two ways: a .env file, or global flags on every command.
Flags always override env vars.
Put flags before the subcommand: --url, --tenant, --username, --password, --ssh, --api-version.
Option A — .env file
Create a .env in this repo (or any parent directory).
acu finds .env by walking up from the current directory, so run all commands from inside this repo.
Required:
ACU_BASE_URL=https://your-instance.example/AcumaticaERP
ACU_TENANT=YOUR_TENANT
ACU_USER=admin
ACU_PASSWORD=...Optional:
ACU_SSH=Administrator@your-host # needed for tenant create / SSH control plane
ACU_API_VERSION=25.200.001 # version half only; must match target.yaml default_apiACU_API_VERSION is the version half only (25.200.001), never Default/25.200.001.
Committed target.yaml declares the verified matrix (erp + default_api).
Live data-plane commands hard-fail when default_api and ACU_API_VERSION disagree.
Sanity-check the resolved target (no password in output):
acu config show
acu config check # includes target.yaml match
acu config check --strict # missing target.yaml becomes failOption B — flags only (no .env)
Pass connection flags before every subcommand:
acu --url https://your-instance.example/AcumaticaERP \
--tenant YOUR_TENANT \
--username admin \
--password '...' \
config check
acu --url https://your-instance.example/AcumaticaERP \
--tenant YOUR_TENANT \
--username admin \
--password '...' \
bootstrap
acu --url https://your-instance.example/AcumaticaERP \
--tenant YOUR_TENANT \
--username admin \
--password '...' \
apply --dry-runPublish AcuBootstrap into the session tenant before any seed apply.
This is pure REST (no SSH required).
When ACU_SSH / --ssh is set, an app-pool recycle follows publish so feature-gated screens load.
acu bootstrapOffline fallback (no HTTP, no password): write the package zip for SM204505 UI import:
acu bootstrap --export AcuBootstrap.zipacu tenant create also publishes bootstrap after create; use bare acu bootstrap when the tenant already exists.
Preview first, then apply:
acu apply --dry-run
acu applyBare acu apply (no paths) defaults to bootstrap/, then baseline/, then setup/ in that order.
Use that after a virgin tenant; use baseline/ setup/ when the Bootstrap package is already published and company seeds are in place.
Apply only loads master data.
scenario/buy-build-sell.yaml is the Lab5 happy path: buy parts from four vendors, receive them, assemble gateway kits (GW-EDGE, GW-CELL, GW-RAIL), sell to three customers, invoice, and collect one payment.
It also asserts inventory and GL deltas, so a re-run stays clean on a warm tenant.
Without this step the tenant has no stock moves, orders, or invoices to inspect.
acu run scenario/buy-build-sell.yamlacu diffZero drift means success.
There are no tests or linters in this repo.
Validation is dry-run, then scenario run, then diff.
# virgin tenant: create + publish bootstrap package, then apply and run
acu tenant create --id N --login NAME
acu apply
acu run scenario/buy-build-sell.yamlacu tenant create needs ACU_SSH (or --ssh).
It is resumable: an existing login skips create and republishes bootstrap.
acu config show # resolved target (.env format, no password)
acu config check # preflight: discovery, secrets, target, REST, endpoints, SSH
acu bootstrap # publish AcuBootstrap package (REST; no SSH)
acu apply --dry-run baseline/ # preview a path
acu apply baseline/30-ledger.yaml # apply a single file
acu apply # defaults: bootstrap/ baseline/ setup/
acu diff baseline/58-order-types.yaml
acu run scenario/buy-build-sell.yaml
acu tenant create --id N --login NAME
acu schema --out schemas/ # dump swagger.json (schemas/ is gitignored)
acu --tenant <TENANT> <command> # override sign-in tenant (no -t short flag)- What — YAML under
bootstrap/,baseline/, andsetup/(one file per config domain). Bareacu apply/acu diffuse those three dirs in that order when given no paths.scenario/is foracu runonly; it is never applied or diffed. - Verified matrix — committed
target.yaml(erp+default_api); not secrets. - Where + who — your
.env(ACU_*vars); keep credentials out of git.
| Path | Role |
|---|---|
bootstrap/ |
Virgin-tenant seeds: features, company, credit terms |
baseline/ |
Lab5 config upserts (GL, inventory, orders, AR/AP/CA, vendors, customers, kits) |
setup/ |
One-shot actions with done_when (financial year, master calendar, open periods) |
scenario/ |
Transaction scenarios for acu run; format contract: scenario/README.md |
target.yaml |
Verified ERP build + Default API generation (default_api must match ACU_API_VERSION) |
.env |
Instance URL, tenant, credentials (gitignored) |
Dual-served entities (Bootstrap contract and Default) need an explicit endpoint: line.
| Value | Resolves to |
|---|---|
| omitted | Default/<ACU_API_VERSION> for Default-only entities |
bootstrap |
active Bootstrap/<ver> from bootstrap/project.xml |
default |
Default/<ACU_API_VERSION> — tracks the operator API version |
Bootstrap/1.8.0 or Default/25.200.001 |
literal pin |
Prefer symbolic bootstrap / default over literal paths so the seed tree travels with the contract and configured API generation.
Apply order is the numbered filename prefix.
Shell glob sorts alphabetically, so every cross-reference must sort after its dependency.
Example: warehouse WH01 is in 53-warehouse.yaml, so it sorts before 54-item-classes.yaml.
setup/ files use the same numbering and run after baseline/.
REST covers apply, diff, schema, and run.
SSH is only for the tenant control plane (acu tenant create).
If the tool fails (bug, crash, wrong diff, missing capability), file an issue on the CLI repo:
gh issue create --repo kborovik/acumatica-cli --title "..." --body "..."Write and edit every .md doc file (README, designs) with the steno skill.
Simple technical language, lead-first sentences, no idiom.
Apply the semantic line breaks convention (sembr.org) to sentences only.
One sentence per line, break at sentence ends, never inside a sentence.
A rendered paragraph needs a blank line, not a wrapped one.