Changelog¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Effort-based Versioning. (Changes to features documented as “experimental” will not increment macro and meso version numbers.)
Unreleased¶
(nothing yet)
2.1.4 - 2025-02-12¶
This is a minor bugfix release.
Fixed¶
- Fix a bug when using
getenv(..., multi=True)
with a non-existing environment variable.
2.1.3 - 2025-02-12¶
This is a minor bugfix release.
Fixed¶
- Fix a bug related to input validation of steps with amended inputs.
2.1.2 - 2025-02-12¶
This is a minor bugfix release.
Fixed¶
- Fix an RPC timeout bug.
2.1.1 - 2025-02-12¶
This is a minor bugfix release.
Fixed¶
- Disable input checking when running a
ValidateAmendJob
. (It is expected that inputs may not be consistent yet at this stage.) This eliminates some false positive input errors.
2.1.0 - 2025-02-12¶
This release improves the overall robustness of StepUp.
Most importantly, table constraints are introduced on the file
table in .stepup/graph.db
,
eliminating potential bugs by design (or making them easier to fix).
The constraints change the database schema,
so graph.db
files created with version 2.0 will be discarded.
The workflow will be completely rebuilt after an upgrade to StepUp Core 2.1.
This release also refactors the implementation of file and step hashes, and worker processes. Finally, error messages and exception handling have been improved.
Added¶
- The log level can be controlled with the
STEPUP_LOG_LEVEL
environment variable. Alternatively, setSTEPUP_DEBUG=1
, which will also activate additional debugging output. (This replaces the formerSTEPUP_STRICT
environment variable.) - Improve handling of unexpected file changes. Before a step is executed or skipped, and after it has completed, changes to inputs (since they were declared static or built by previous steps), will cause the step to fail and the scheduler to drain. (This feature requires a database schema version increase.)
Changed¶
- Because of other database schema changes in this release,
also the
FileState
enumeration was relabeled in a more chronological order. - The
cleanup
command always runs in the most verbose mode (-v
no longer supported). It now also supports the-d
or--dry-run
option to show which files would be cleaned. - The variable
${STEPUP_EXTERNAL_SOURCES}
can now also contain relative paths, which are assumed to be relative to${STEPUP_ROOT}
. - The default timeout for RPC calls has been increased from 5 to 300 seconds.
It can be controlled with the
STEPUP_SYNC_RPC_TIMEOUT
environment variable. Setting it to a negative value will disable the timeout and make RPC calls wait indefinitely for a response.
Fixed¶
- Table constraints are introduced to ensure file states and hashes are consistent. This eliminates some difficult to reproduce bugs or makes them easier to fix. (This change requires a database schema version increase.)
- Code documentation updates and internal cleanups.
- Renaming and moving directories in watch phase is now handled correctly.
- Fixed routine to wipe database in case of a schema version change.
- Add safety check to prevent two StepUp instances from running in the same directory.
- Add a warning when errors are reported in
.stepup/director.log
. - When running StepUp with the
-w
option and the scheduler is drained, queued steps are now made pending again, ensuring they are only executed when appropriate.
2.0.7 - 2025-02-06¶
This release fixes two recursive glob issues.
Fixed¶
- Fixed issues with directories matching
glob("...", _defer=True)
, which are later used as parent directories in various scenarios. - Fix bug in recursive glob to match
data/inp.txt
with the patterndata/**/inp.txt
2.0.6 - 2025-02-05¶
This release introduces the STEPUP_EXTERNAL_SOURCES
environment variable
for more fine-grained control over automatic dependency tracking.
Added¶
- The
STEPUP_EXTERNAL_SOURCES
environment variable can be set to a colon-separated list of directories with source files outsideSTEPUP_ROOT
. Thescript
andcall
drivers use this to decide which imported Python modules to consider as inputs to a step.
Changed¶
2.0.5 - 2025-01-28¶
This is a minor release, just adding a utility function.
Changed¶
- Use
string_to_bool
to interpret the environment variableSTEPUP_STRICT
. E.g., setting it to"0"
will disable strict mode.
2.0.4 - 2025-01-28¶
This release fixes very minor issues. It is mainly for testing release automation.
Fixed¶
- Use
importlib.metadata
instead of_version.py
to get the version number. - Add
--version
option tostepup
command. - Improve screen output consistency.
2.0.3 - 2025-01-27¶
This release fixes one pesky bug.
Fixed¶
- It was previously not possible to reattach an orphaned step to a different creator when this step was not a top-level orphan. This limitation has been lifted, because it is a fully legitimate use case.
2.0.2 - 2025-01-25¶
This release fixes several bugs.
Added¶
- Environment variable
STEPUP_STRICT
to enforce strict mode. This disables automatic fixes in the database that can only be caused by bugs.
Fixed¶
- A bug is fixed in the logic to determine the type of job to run for a given step. Some steps were executed while not all required inputs were present.
- A bug is fixed that caused optional steps not to be executed again, when their inputs had changed or their outputs were removed.
- A bug is fixed that caused outputs of steps to be removed when they were changed
from
optional=False
tooptional=True
. - Occasionally,
.stepup/
was not created yet when the reporter tried writing to.stepup/success.log
. - When multiple steps were changed and StepUp is restarted, steps created by a by another modified step were executed before the creating step. This is fixed.
- Fix a few issues found by deepsource.io.
2.0.1 - 2025-01-22¶
(Version 2.0.0 was yanked due to a packaging issue.)
Added¶
- New option
-W
or--watch-first
to automatically rerun steps after a file has changed. - Press
q
a second time to kill running steps with SIGINT, similar to ctrl-c. - Press
q
a third time to kill running steps with SIGKILL, nuclear option. stepup
has a meaningful returncode:0
= all mandatory steps succeeded1
= internal error (Python exception)2
= at least one step failed3
= no steps failed, but some remained pending
- Failed steps (if any) are also logged to
.stepup/fail.log
, which is more convenient to inspect than scrolling back in the terminal. Similarly, all warnings (if any) are written to.stepup/warning.log
. --perf
option to analyze performance bottlenecks in the director process.- The “call” protocol is added as a light alternative to the “script” protocol.
It can be used through the new
call()
function. getinfo()
function to retrieve theStepInfo
object of the current step.- Cleanly exit the director process upon several types of exceptions (instead of hanging).
- Gracefully handle
SIGINT
andSIGTERM
, e.g. pressingctrl-c
in the terminal.
Changed¶
-
Breaking changes to
stepup.core.api
:- The
getenv()
function has been extended and now has three options (path
,rebase
andmulti
) to control how the environment variable gets processed. - The optional
workdir
argument of thescript()
function must always be specified as a keyword argument. - The
block
argument of theplan()
function must be given as a keyword argument. - All optional arguments of
copy()
andmkdir()
must be given as keyword arguments. plan.py
scripts must start with#!/usr/bin/env python3
instead of#!/usr/bin/env python
.- The
amend()
function now raises an exception when the amended inputs are not available yet, instead of returningFalse
.
- The
-
Backward compatible changes to
stepup.core.api
:- The
script()
function has an extrastep_info
option to specify a file to which thestep_info
objects of the run part(s) is/are written. This comes with an extension of the script protocol:./script.py plan
must accept an optional argument--step-info=...
- The
script()
function now accepts all arguments that can be passed on to the underlyingstep()
call. There are only relevant for the plan stage of the script protocol. - The script
driver()
now detects local imports in therun()
function of the script and amends them as inputs. - The
plan()
function now accepts all arguments that can be passed on to the underlyingstep()
call.
- The
-
Command-line and terminal interface changes:
- By default, StepUp will exit after having executed all runnable steps.
Use the option
-w
or--watch
to keepstepup
running and watching for file changes. - Keyboard interaction works with and without the (new)
--watch
option. - The
cleanup
script now also works whenstepup
is not running. It also features an improved verbosity option.
- By default, StepUp will exit after having executed all runnable steps.
Use the option
-
Terminology changes:
- The “supplier ➜ consumer” graph is now called the dependency graph.
- The “creator ➜ product” graph is now called the provenance graph.
-
Internal changes:
- Complete refactoring of the internal workflow data structure, file format and the core algorithms. For example, if some files change, StepUp can better narrow down which steps are worth rerunning.
- The workflow is now entirely stored in an SQLite database, in
.stepup/graph.db
, which has major benefits:- When an RPC call modifies the workflow and causes an exception, the workflow rolls back to its last known valid state (before the RPC call), thanks to SQLite’s ACID properties. This eliminates many potential bugs by construction.
- Upon restart, StepUp can continue without noticeable delay where it last stopped, because its entire last-known state of the workflow is readily available. StepUp only needs to check for changed files and environment variables to decide if (additional) steps need to be made pending.
- If something goes wrong unexpectedly in a complex production workflow,
the
graph.db
file can be inspected withsqlitebrowser
to debug the issue and potentially derive a small test case to be added to the unit tests. The use of SQLite adds a (small) computational overhead compared to storing the same information in native Python data structures. This release has not been extensively optimized for performance.
- Improved tracking of file changes. Unexpected changes to input files of steps in the run phase will cause an exception.
Removed¶
- StepUp no longer uses
msgpack
and uses pickling for serialization instead. Themsgpack
dependency has been removed. Relatedstructure()
andunstructure()
methods have been removed. - The
-f
or--workflow
argument of the director server has been removed. - The
f
(from scratch) andt
(try replay) keys have been removed from the terminal user interface.
Fixed¶
- When static file has been deleted (missing) and later restored, the restored file was not noticed when restarting StepUp. This is fixed.
- Tests have been made compatible with Python 3.13.
- Files with whitespace are handled correctly. (That being said, we don’t recommend using files with whitespace.)
1.3.1 - 2024-09-17¶
Fixed¶
- Fix incorrect parsing of
?*
and*?
wildcards in thenglob
module.
1.3.0 - 2024-08-27¶
Added¶
- Add support for standard output and error redirection in the script driver.
The dictionary returned by the
info()
orcase_info()
functions can include"stdout"
and/or"stderr"
items. The values of these two fields are paths to which the standard output and/or error of the run part of the script are redirected. - All API functions that define a step now return a
StepInfo
instance, which may contain useful information (e.g. output paths) to define follow-up steps. This is mainly useful for API extensions that define higher-level functions to create steps, e.g. as in StepUp RepRep. - The classes
NGlobMulti
has a new methodsingle()
andNGlobMatch
has a new propertysingle
. These are only valid when there is a unique match, i.e. when thefiles()
method or property has exactly one path.
Changed¶
- Migrate
load_module_file
to stepup-reprep. - Replace watchdog by asyncinotify to avoid a long-standing issue in watchdog.
- :warning: API-breaking :warning:
When a step is defined with a working directory different from
'./'
, relative paths provided in other arguments to thestep()
function are interpreted relative to the given working directory, not the current working directory of the running process. - The directory
.stepup
is no longer created when runningstepup
without aplan.py
. - The files in
.stepup/logs
have been renamed to*.log
files under.stepup
.
Fixed¶
- Fix bug in the translation of relative paths before they are sent to the director process.
- Add trailing slash to
workdir
argument ofstepup.core.api.step()
if it is missing. - Fix mistake in worker log filenames.
- Fix bug in back translation of paths when substituted in a step command.
- Improve compatibility of nglob with Python’s built-in glob.
1.2.8 - 2024-06-28¶
Fixed¶
- Modify the script driver so that
info()
andcase_info()
may return empty dictionaries.
1.2.7 - 2024-06-24¶
Fixed¶
- Add workaround for Python==3.11 bug with RPC over sockets.
The RPC server (created with
asyncio.start_unix_server
) closes before all requests are handled. A stop event is now included for all RPC handlers to wait with stopping the server until every request is handled. This is a known issue fixed in Python 3.12.1.
1.2.6 - 2024-06-13¶
Fixed¶
- Do not watch files when running StepUp non-interactively. This makes non-interactive mode a workaround for a nasty watchdog bug.
1.2.5 - 2024-06-13¶
Fixed¶
- Effectively make watching recursive when a directory is added that is known in the workflow.
- The function
amend()
now always returnsTrue
when the RPC client is a dummy. This fixes early exits from scripts that usedamend()
when they are called manually. - Prevent the
Cannot watch non-existing directory
error by ensuring that deferred glob matches exist before they are included as static files in the graph. - Check that local scripts have a shebang line before trying to execute them.
- Improved continuous integration setup
- Minor documentation improvements
- Minor code cleanups
1.2.4 - 2024-05-27¶
Changed¶
- Include “hidden” files when globbing.
Fixed¶
- Do not refuse to replay unchanged step that declares its own static inputs.
- Make recursive glob consistent with Python’s built-in glob in
step.core.nglob
. - Pool definitions are stored in workflow and replayed correctly when a step is skipped.
1.2.3 - 2024-05-19¶
Changed¶
- Completed and revised docstrings in
stepup.core.nglob
, and added this module to the reference documentation.
Fixed¶
- Improve hash computation of a symbolic links in
stepup.core.hash
.
1.2.2 - 2024-05-16¶
Changed¶
- Documentation updates.
Fixed¶
- Make
cleanup
command work in project subdirectories whenSTEPUP_ROOT
is set. - Avoid useless wait when running a
plan.py
script outside ofstepup
.
1.2.1 - 2024-05-07¶
Fixed¶
- Fixed packaging mistake that confused PyCharm and Pytest.
1.2.0 - 2024-05-02¶
Added¶
- Export of graphs to Graphviz DOT files.
- The
cleanup
script for manually cleaning up outputs.
Changed¶
- Documentation updates.
- Limit acyclic constraint to the supplier-consumer graph. This means a step can declare a static file and then amend it as input.
- Refactoring of the file
stepup.core.watcher
module:- Replace dependency
watchfiles
bywatchdog
. - Rename functions in
stepup.core.interact
:watch_add()
->watch_update()
watch_del()
->watch_delete()
- Separate watcher and runner coroutines with reduced risk for race conditions related to
watch_delete()
andwatch_update()
to addressTimeoutError
. - Place custom asyncio utilities in
stepup.core.asyncio
. - The watcher also tracks changes to static files while steps are being executed.
- Directories are watched as soon as they are created.
- Replace dependency
- The function
stepup.core.interact.graph
takes a prefix argument instead of a full filename, e.g.graph
instead ofgraph.txt
.
Fixed¶
- More graceful error message when the director process crashes early.
- Fix compatibility with asciinema terminal recording.
- Raise
ConnectionResetError
inSocketSyncRPCClient
instead of blocking forever when the director process crashes.
1.0.0 - 2024-04-25¶
Initial release