All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog. This project adheres to Semantic Versioning.
dr workload upreads why an errored workload is errored off the platform's per-replica status details and prints it beside the state, in the plan and in the refusal:ErrImagePullwith the registry's answer, orCrashLoopBackOffwith the exit code of the run that failed. Under--output-format jsonthe plan carries it asplan.stateReason. A rollout that endserroredorfailednow also carries the platform's own message for it.dr workload config --sync-envanddr workload up --sync-envmake.datarobot.yamlsay what.envsays. One flag rather than one per half, because "make these two agree" is the thing people want and splitting it made them work out which half applied to what..envwins on every variable: on the value, on the form the entry takes, and on whether the entry exists at all. A name it does not carry is added, a value that moved is rewritten, a literal it now reads as a secret becomes a credential reference and the reverse becomes a literal, an entry an earlier run left on the credential placeholder is finished, a value the manifest kept as a mapping or a list becomes the string.envhas for it, and a name.envno longer mentions is removed. This reverses the additive, one-directional rule the import used to follow, and it is why the run shows its work and asks. It prints a table of every variable the two files have anything to say about, what it will do to each and why, and asks before it writes a line or sends a value.--yesis the only consent that counts:DATAROBOT_CLI_NON_INTERACTIVEsuppresses wizards in CI and is not agreement to overwrite a value on a tenant-wide credential store, which is the linedr workload deletealready draws, so a run with no terminal and no--yesrefuses and names the flag. A dry run prints the table and applies nothing. Refusing is a decision rather than a failure: nothing is written, nothing reaches the tenant, and a deploy carries on with the file as it stands. With.envwinning on everything, a stale local copy is enough to delete a variable a running workload depends on, or to deploy alocalhostURL the classifier used to withhold. The classifier now decides only what form an entry takes, secret or literal, and no longer whether the variable travels; the table is where its verdict is overruled, and a value it once hid can land in the manifest in the clear, which the run discloses by name. A project with no.envat all is left alone rather than emptied, because the ordinary CI checkout has none, and so is one whose.envdeclares nothing: atouch, or a secrets step that wrote an empty file before a scheduled run passed--yeson its behalf, is not an instruction to delete the environment. A manifest whose environment is shared through a YAML anchor takes no edit, since rewriting or dropping an entry would change it for every container reading the same node: a run with only secrets to re-send goes through, after the same question every other re-send gets, and one with file work to do is refused before the question rather than half-applied. Secrets are stored as credentials the way setup stores them, and a re-send goes only to a credential this project created, checked by name first: the store is tenant-wide, so an id pasted by hand may name one other workloads read. A secret is re-sent without being compared, because it cannot be. The file is edited in place, so comments, entry order and hand-tuned keys survive, and the edit is rendered and thrown away once before any credential is created, so a file the write would refuse never leaves a credential behind that nothing points at.dr workload configover an existing manifest now names the.envvariables the file does not declare, and the flag that adds them. Names only, never values, matching what the deploy plan already redacts. Silent when there is no.env, which is the ordinary CI case, and under--skip-env. Under--output-format jsonthe wizard is given no stderr at all, so2>&1 | jq .parses; the one thing that would otherwise be lost, a.envthat could not be read, becomes an error there rather than a warning nobody sees. It also names a declared variable whose.envvalue no longer matches the manifest, and the variables stored as credentials, whose values cannot be compared at all: saying so outright beats a silence that reads as "those are fine" while a rotated key sits unused. And it names what was held back rather than added: a variable the classifier read as local-only, and an entry left naming the credential placeholder by a store that could not be reached, which a later import skips because the name counts as declared.dr workload status,dr workload get,dr workload endpointanddr workload logsnow take the workload id as an optional argument. Left out, it is read from theworkloadIdin the nearest.datarobot.yaml, searched upward from the new--dirflag (the current directory by default), so the commandsdr workload uppoints you at can be run as printed from the project it just deployed. A typed id still wins, and is used without reading any manifest. The workload that was picked is named on stderr, except under--output-format json, where anything on stderr would break2>&1 | jq ..dr workload stop,dr workload startanddr workload deletetake the workload id optionally too, on the same terms. Because they change something, a workload whose id is specified in the manifest rather than on the command line is confirmed first; a typed id is never questioned.--yesskips the question, andstopandstartgained that flag for this.DATAROBOT_CLI_NON_INTERACTIVE=1also skips it onstopandstart, but not on adeletewhose id came from the manifest: that variable is set once across a pipeline, and deleting something nobody named is not what it was set for.dr workload delete --dir <path>: which project's manifest holds the binding to clear, matching the flagupandconfigalready take.
- The
dr workload configsetup wizard, whichdr workload upalso opens for a project with no manifest, no longer shows a fresh directory's suggested name as one you typed. Choosing another directory on the way back, or setting up a new workload after looking at an existing one, rebuilds the draft from this run's flags, but the mark that says the name was given by hand outlived the draft it belonged to, so the new directory's suggestion came back filled in as a value. One reflexive Enter could then put a name likesrcon a deployed workload, which is what the name screen exists to prevent. The draft and that mark now start over together, so the suggestion is offered as a placeholder again; a--namestill counts as given, because that answer belongs to the run rather than to the draft being replaced. dr workload upnow deploys onto an errored workload instead of refusing it, whenever the deploy gives it something new to run: a code change, a change to the manifest or the sizing, or--force-build. What the workload is running has failed, so there is nothing serving for the swap to endanger, and the plan says so with the platform's own reason for the failure beside the state. A deploy with nothing new in it is still refused, and the refusal names what would work:--force-buildfor a project whose image the platform builds, a change to the image or artifact otherwise, and the delete as the last resort. An errored workload never has its image copied forward, since on a locked version the copy would be locked too, permanently, pointing at an image the registry may no longer have; the version is built instead. A stopped workload whose start comes up errored ahead of a roll is rolled anyway, and the name conflict on an errored holder advises binding to it again. Together these close a deadlock in which a locked production workload whose image the registry had pruned could be neither deployed onto, nor started, nor rebuilt.dr workload up --force-buildnow rebuilds and rolls even when the working tree and the manifest have not changed, which is the case the flag exists for: an image gone from the registry leaves both exactly as they were. The flag used to be read only by the build step, so a plan with nothing else in it came out empty and the run reported the workload as up to date. A forced build on a locked version locks its successor to match; on a manifest that names its image rather than building it the flag stays idle and says so.dr artifact code syncanddr workload upnow name the File Registry entry they createArtifact: <id>, instead of leaving it on whatever the platform picked. The Files API takes a name only at creation and the CLI was never sending one, so what the Registry showed was an accident of which upload route ran: a change set small enough for the stage route landed asUntitled Dataset, and anything over 20 files or 50 MB landed aswapi-sync.zip, the CLI's own temporary filename, because the platform derives a title from the uploaded file when nothing else names it. Neither says whose code it is, and since the Registry accepts duplicate names without complaint, a tenant ended up with a column of identical rows and no way to tell them apart short of a hand rename. The artifact's name is deliberately not what goes in: naming is create-time only, so whatever goes in is what the entry shows for the rest of its life, and a name the project is free to change afterwards would end up telling a reader something that had stopped being true, which is the same defect as the default titles and harder to spot. It would not identify the row either, since nothing stops two projects from choosing the same artifact name anddr workload upderives that name from the directory. The id names the artifact that created the entry, which is not always the one deploying from it later: every successfuluplocks the artifact it deployed and mints a fresh one for the next deploy, while the catalog stays where it is. A locked artifact is kept rather than deleted, so the id goes on resolving and goes on being true about where the code came from, naming the first version of the lineage rather than the current one. A large first sync now creates its catalog before uploading, rather than in the same request: the name travels on the create call, which is the only route that tolerates it everywhere, since that route took no request body before the parameter existed while the create-from-file route validates its form strictly and would reject an unknown field outright. The cost is one extra request on a first sync, and it makes the two upload paths the same shape.dr artifact code syncanddr workload upnow replace files in the catalog when the upload takes the zip route, which is any change set of more than 20 files or 50 MB. The overwrite mode was sent only as a query parameter of the Files API'sfromFileupload, which the server accepts and ignores, so its rename default applied: every path already in the catalog came back as aname (2).extduplicate holding the new bytes while the original kept the old ones, the version had twice the files, and an image built from it ran stale code next to junk. Smaller change sets, which go through a stage, were never affected. The mode now travels in the multipart form, ahead of the file, where the server reads it; it is still sent in the query as well until the API says which of the two is authoritative.dr workload upnow says when.envand the manifest have parted, instead of reporting a deploy as up to date without having looked at the file you just edited. Nothing is applied and nothing is written: a deploy stays a function of the committed repo, and reading the file to say the two disagree is not deploying from it. The notice is the onedr workload confighas printed all along, names only and never values, and it names the one flag that settles it, on the command you are already running rather than sending you to a different one, carrying the--dirthis run was given becauseconfiglooks only where it is pointed whileupwalks upward for the manifest. Silent where there is no.env, which is the ordinary CI case, and silent where the two files agree. What is left toconfigis everything that is true of the project rather than of this run: the values behind credential references, which nothing can compare; the names the classifier read as local-only, which no flag will ever add; an entry left naming the credential placeholder, which the deploy refuses for itself when it reaches it; and a manifest whose shape no flag can edit, whose refusal counts the whole of.envas missing. None of those can be settled by anything the reader is about to run, so on a deploy each would print on every run for the life of the project, and a line that always prints is one you stop reading along with the drift beside it.dr artifact code syncno longer overwrites or deletes a local file without a recoverable copy. Before the remote wins, your version is saved as<path>.LOCAL.<timestamp>, for every case that touches the working tree — not only conflicts, as before — including a remote-modified download that used to be applied silently with no backup. Those.LOCALcopies are also excluded from the next sync, so a backup is never re-uploaded as new content.dr workload deletenow clears aworkloadIdwritten as a YAML alias. The reader resolves the alias before answering, so such a binding is the one the project deploys to, but the removal compared the unresolved node and left the file as stale as it found it while reporting the delete a success.dr workload up --dir <path>now says which flag named a path that is not a directory, instead of failing with a barenot a directory, matching whatdr workload delete --diralready said.- An empty
.datarobot.yamlnow gets one explanation and one remedy whichever command reaches it, rather than a generic "root must be a YAML mapping" from the write path and a friendlier sentence from the read path. - The confirmation
stop,startanddeleteask about an id they read from a manifest now says where the id came from and why it is asking. "Named by.datarobot.yaml" meant designated by, but the manifest carries a realname:key, so it read just as easily as "its name comes from this file". dr workload upno longer shortens the workload id in the line warning that a binding no longer resolves. Comparing that id against the file is what tells a deleted workload apart from a run whose token resolves to a different instance or organisation, and eight characters is not enough to do it with.- The three
dr workload uprefusals that tell you to delete a dead workload and deploy again now say what that costs: the replacement keeps the name but is a new workload with a new id and a new endpoint URL, so anything calling the old URL has to be repointed. The errored refusal previously said only "recreate it under the same name", and the terminated and name-conflict ones said nothing about it at all. dr workload config --dir <path>now refuses a path that is not a directory, by name, the waydr workload upanddr workload deletealready did. It was the one command in the family that did not check, so a typo produced a warning naming an ancestor you never typed, then a warning about missing project files, then an error about a missing Dockerfile, none of which said the directory was not there.- The confirmation before rolling a locked version no longer claims the version is production. Locking makes an artifact immutable; why it was locked is not something the CLI knows.
-
dr pipelineis now generally available and no longer feature-gated. The command was hidden from the command tree, shell completion anddr --helpunlessDATAROBOT_CLI_FEATURE_PIPELINE=truewas exported; it is now registered unconditionally, and the note calling pipelines a Private Preview is gone from its help text. Nothing about the subcommands or their flags changed, so a script that set the variable keeps working — the variable is simply no longer read for this command.dr workloadanddr artifactremain gated behindDATAROBOT_CLI_FEATURE_WORKLOAD; only thepipelinegate was removed. The two reference pages,commands/pipeline.mdandcommands/pipelines-reference.md, existed but were absent from the docs navigation, so the only way to reach them was to already know the URL; both are now listed under Commands and no longer open by telling you to turn a feature flag on. The command tree in the command reference also documented adr pipeline environmentsubcommand that has never existed under that name — the code registersimage— and omittedcloneandsourceentirely; all three are corrected. -
dr artifact code syncno longer lets the remote silently win over your local changes. When a file changed both locally and on the remote (a conflict), an interactive run asks before pulling, and a non-interactive run (--yesorDATAROBOT_CLI_NON_INTERACTIVE) is now refused unless you pass the new--accept-remoteflag — so an automated sync fails loudly instead of overwriting your edits. This is a behavior change for CI: a pipeline runningdr artifact code sync --yesthat hits a conflict will now exit non-zero where it previously applied remote-wins; add--accept-remoteto opt back in (your versions are still saved as*.LOCALcopies). A plain pull of a remote change you had not touched still applies without prompting. -
dr workload upno longer pastes the workload id into the commands it suggests running next. They are printed as they can be typed from the project it just deployed, carrying--dirwhen the deploy did. A run that failed after creating the workload names the id above them instead, because that is the one case where the manifest holds no binding for them to resolve. -
dr workload deletenow removes theworkloadIdit wrote from a.datarobot.yamlbound to the workload it deleted, so the nextdr workload upis not pointed at something that no longer exists. Only a manifest naming that exact id is touched, the id is compared inside the same edit that removes it, and the artifact link under.datarobot/is left alone so the next deploy reuses the artifact; the command names that artifact and how to unlink from it. A workload that was already gone leaves the binding alone: a 404 means "not on this instance", which is not proof the binding is stale. -
dr workload upnow mints a new artifact when the one this project is linked to no longer says what.datarobot.yamlsays. An artifact's spec is fixed when it is created, so reusing a diverged one deployed the frozen answer and reported success. A read that fails is not treated as a difference: the run stops and names the artifact it could not read, so a timeout never starts a new artifact lineage. -
dr workload upnow treats a binding that resolves to nothing as drift and creates a new workload, instead of refusing and asking for the id to be cleared by hand. The plan and the JSON envelope both name the id it could not find, so a run pointed at the wrong instance is visible rather than silent. A terminated workload is still refused, because it continues to exist and to hold its name and artifact; the message now namesdr workload delete, which clears the way and the binding together. -
--import-envand--update-env, which the v0.5 releases shipped ondr workload configanddr workload up, are removed;--sync-envreplaces both. Passing either now fails withunknown flag. Replace it with--sync-envand expect two differences beyond the name: the run prints what it will do to each variable and asks first, so a script needs--yes, and a name dropped from.envis removed from the manifest rather than left alone. -
dr workload upnow names the field that moved in the change plan it prints, rather than the whole path to it. Every path the walk produces threads throughcontainerGroupsandcontainersbefore it reaches anything a person wrote, so a line spelling the whole of it out was mostly scaffolding, and on a terminal narrower than the path it wrapped and buried exactly the part being read. The scope is printed once above the changes that share it, and dropped where naming it would say nothing. The whole path is still what--output-format jsoncarries, for anything that acts on a change rather than reads it. The redaction that keeps environment variable values out of the plan now reads the walk's own keys rather than the rendered path, so a change to how a path is spelled cannot quietly take the redaction with it.