Deploy from a repository
Start by installing the CLI and signing in. Then pick the path that matches what you have.
Two commands do different things, and it is worth knowing which one you are running:
- A single folder’s
push—ronja wf push,ronja app pushand the others — sends the folder to your own draft. Nobody else sees it until youpublishit.ronja automation pushis the exception: an automation has no draft, so its push changes the live automation at once. ronja sync applypushes and publishes every folder under the directory it runs in. What it deploys is live as soon as it finishes.
Edit one existing resource
Section titled “Edit one existing resource”For a quick change to one workflow, App, module or Feature’s tables, with no repository set up:
- Copy it into a folder:
ronja wf clone <workflow ID>, then go into the folder it names. - Edit the files in your own editor.
- Run
ronja wf pushto send them to your draft. - Run
ronja wf testto run the draft and see its result. - Run
ronja wf publishto take it live.
Apps work the same way with ronja app. Modules (ronja module clone <module ID>) and a Feature’s tables (ronja pipeline clone <Feature ID>) use clone, push and publish, with no test step. See Work on Ronja from your editor.
Adopt a repository you already deploy from
Section titled “Adopt a repository you already deploy from”If you already push folders from a repository, let Ronja keep the record of what each one deploys, so a build server needs nothing committed by hand. Each folder must already name the stack in ronja.json, with its Feature’s ID as featureID; a folder that does not is reported no_feature and left unchanged.
- Run
ronja sync adopt --stack prodat the top of the repository. - Commit the changed
ronja.jsonfiles. - Run
ronja sync apply --stack prod --dry-runto see what a deploy would do, thenronja sync apply --stack prod.
Once adopted, a folder writes and runs only inside its stack’s Feature. A workflow that writes a table in another Feature, or runs a workflow or Saved Agent there, is refused (writes_outside_target, runs_outside_target) until that dependency is declared in ronja.json with "write": true or "run": true and set in the stack’s bind map.
Running ronja sync adopt again is safe. To stop a folder keeping its records in Ronja, run ronja sync unmanage.
Import a Feature and deploy it
Section titled “Import a Feature and deploy it”To start a repository from what a Feature already holds:
mkdir sales && cd sales && git initronja import feature Sales # the Feature's folders, on stack "main"git add -A && git commit -m "Import Sales"ronja sync status --stack main # clean: the tree holds what is live
# edit files, commit, then:ronja sync apply --stack main --dry-run # what the deploy would changeronja sync apply --stack main # push and publish every changed folderIn the dry run, everything that already matches what is live is listed as unchanged — a workflow, App or module folder, and each table, metric and automation file — and the deploy changes nothing for it. (If Ronja has no record yet of a row the folder’s ronja.lock.json names, the dry run says the deploy adds that record; that changes nothing you deployed.) If someone changes something in Ronja that the repository deploys, the next deploy stops and names it; run ronja <kind> pull to take the change into the folder, and commit it.
An import names what each folder reads by the folder that builds it where it can, so the same repository can deploy elsewhere. It leaves two kinds of ID in place and lists them: a table a workflow’s code replaces by its ID, and IDs written into an App’s source. Before deploying to a second stack, change each tools.replaceTable(df, "table-…") it lists to tools.replaceTable(df, {{ write('<name>') }}) with the name it gives, and the App’s IDs by hand. Letting Ronja keep the records of tables and metrics needs an Admin, so anyone else’s import writes no pipeline folder and lists the tables and metrics it left out.
Deploy to a second stack
Section titled “Deploy to a second stack”A second stack — a test Feature next to production, say — deploys the same repository somewhere else. Two limits shape how you do it, so read them first:
- Use a separate checkout for each stack. A checkout remembers what it last deployed per organization, not per stack, so deploying a second stack of the same organization from the checkout that deployed the first can be refused as drift, because it is compared with the first stack’s record. Clone the repository again for the second stack. A build server that starts from a fresh checkout every run is not affected.
- An organization has one copy of each module. A module’s name is unique in the organization, so every stack deploys a module to the Feature it already lives in, and deploying any stack publishes that one copy. Each workflow keeps running the module version it was last published with until it is published again.
Then, in the new checkout:
-
Add the stack to every folder’s
ronja.json, next tomain: the sameurlandtenantID, and the second Feature’s ID as itsfeatureID(for a module folder, the Feature the module already lives in). -
Run
ronja bind --stack <name>in each folder to choose what that stack reads. It never fills in what the code writes ("write": true) or a workflow or Saved Agent it runs ("run": true), because the match it would find is production’s: set each of those by hand in that stack’sbindmap inronja.json, to a row in the new Feature. A workflow’s own output ("output": true) needs nothing: its first run on the new stack makes it in the new Feature.A table one of the repository’s own workflows writes is not something to look up by name either: name it by that workflow’s folder, so each stack reads its own copy. An import already writes it that way. In the reading folder’s
ronja.json,fromis the workflow folder’s path andaddressis the name the workflow gives the table, and the folder needs"formatVersion": 7:"dependencies": {"weekly_revenue": {"kind": "table", "from": "../../workflows/compute-weekly-revenue", "address": "weekly_revenue"}}A table a pipeline folder builds is named the same way, with its
.sqlfile asaddress. -
Run
ronja sync apply --stack <name> --allow-create. Without--allow-create,sync applyonly updates what already exists and refuses to create anything. A folder that reads a workflow’s output is refused until that workflow has run once on the new stack: run it (ronja wf run --stack <name>in its folder), then apply again.
Take a change made in Ronja into the repository
Section titled “Take a change made in Ronja into the repository”Anyone can still change something a repository deploys — in Ronja, by asking Ronja, or from a folder of their own — and it is marked Managed in git while they do. The repository’s next deploy stops on the change. To keep it:
- Run
ronja <kind> pullin the folder:ronja wf pull,ronja app pull,ronja module pull,ronja pipeline pullorronja automation pull. - Read the diff it prints. The folder’s files now hold what is live.
- Commit the changed files.
The next ronja sync apply writes nothing for that folder. --dry-run shows the diff and changes nothing.
A pull reads only what is live, never a draft, and never replaces a change of your own that has not been deployed: it stops and names your files. Deploy your change first and combine the two by hand, or pass --force to replace your change with what is live. It also stops on changes you have not committed. Each refusal says why and what to do next.