Changelog¶
All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]¶
[0.2.0] - 2026-10-07¶
Added¶
$${…}writes a literal${…}.apply: [sh, -c, 'echo $${HOME}']hands the shell${HOME}; before, there was no way to write one. The error for a${…}that is no reference says so, and names a step only when one above gives a value of that name.
Changed¶
- What a step's program says is shown while it runs.
bundle deploy,bundle destroy,bundle runand acommandstep's apply and destroy commands are passed on a line at a time, as they come, on stderr — what they write to stdout and to stderr. Before, a deploy or a long job run was silent until it ended, and a warning from a program that succeeded was never shown. - The source package holds the code, its tests and the files that say what it is. It also carried the docs site, the specs, the workflows and the lock file, and was five times the wheel's size. The wheel is as it was.
Removed¶
lely.step.StderrLogandlely.planfile.outputs_json: nothing used them.
Fixed¶
- A program that fails is quoted on both of its streams, each under its name. One that gave its reason on stdout and a notice on stderr was quoted for the notice alone.
- The README's quickstart can be followed: it shows the plugin file its config names. A
test checks every whole config in the README and the docs the way
lely validatedoes. lely doctorlooks for git, as the docs said it did: git missing or refusing the checkout, in a repository, is a failed check —lely planfails there. It compares the Databricks CLI's version with v1.3.0 and says when it is older, and says what bundles need only to a project with a step that runs the CLI.lely doctordoesn't fail for a Databricks CLI no step runs. In a project of commands a missing CLI is said, and is no failed check.- Why a run's record couldn't be written is shown, not obeyed: the error's own words went into the line as markup.
lely doctorsays a plugin that fails in one line, with the step and the plugin, and checks the rest. A plugin whoseprogramsraised ended it in a traceback.- A traceback never shows local values. With a typer below 0.23, an error lely didn't
expect printed every frame's locals, and the frames of
planandapplyhold the run's token and the environment. lely applywith neither a plan file nor-tis refused at once, with 2. It reached the workspace first, so without credentials it failed with 1 instead.- Every
--helpnames[tool.lely]again. It read "a pyproject.toml with . Found from here up": the brackets were taken for markup. So did whatlely schema -osays of apyproject.toml. - lely asks for a typer it works with:
typer>=0.17.5, where 0.1.0 said>=0.12. With an older one every--helpcould end in a traceback, or a command given no-tcould run without one. CI now runs the tests on the oldest version of every dependency.
[0.1.0] - 2026-10-07¶
The first release, as alpha: this is what is built.
Added¶
- One plan for a whole deploy.
lely.yml, or[tool.lely]inpyproject.toml, lists steps in the order they run; each is done by a plugin. A step takes what a step above it gives (${steps.<name>.<output>}) and values from the environment (${env.NAME}, always a secret).lely validatechecks all of it offline and prints the wiring. lely planplans every step and changes nothing. Each step is ready, waiting — it takes something that doesn't exist yet — or skipped, and the plan says which and why.--destroyplans a teardown, from the bottom up.lely applyandlely destroyrun a plan: a reviewed file (lely plan -o plan.json), or planned on the spot with-t. Nothing runs unasked — a terminal to answer at, or--yes— and a destructive change needs--allow-destructive. Every step is planned again right before it runs, and may do nothing the approved plan didn't show.- A plan file is held to what it was made for: the workspace, the steps as written, and the git tree of a clean checkout. It keeps no secret.
lely statuslists what exists because of each step, with links;lely showshows a saved plan;lely doctorsays which tools and which workspace lely finds.- Plugins.
bundledeploys a Databricks Asset Bundle with the Databricks CLI's direct engine;commandruns commands you give it, with an optional plan and destroy command;bundle.runruns a job or pipeline of a bundle step. A class in the repo (./ops/steps.py:Class) or in an installed package is a plugin too.lely stepslists them,lely schemawrites a JSON Schema of the config for editors, andlely.testingholds a plugin to the contract. - GitHub. With
--github, in a GitHub Actions run, the plan is one comment on the pull request, kept current, and the run's page says what was planned or done.-f mdprints the same Markdown.docs/GITHUB.mdhas workflows to copy. - A page.
lely ui plan.jsonmakes one HTML file of a plan — or of a run's record, written byapply -oanddestroy -o— with nothing to fetch and nothing that runs. A plugin can give its plan a view of its own; the bundle shows every resource by type.
Known limits¶
- Tried on a real workspace and on GitHub a few times, with small bundles: a first proof,
not a track record.
README.md, "What has been tried", says what was and wasn't. - The
stevinplugin plans and can't apply yet.