← all releases

v1.5.0

on GitHub

Not the newest. v1.5.1 is out →

Release notes

Added

  • The Web UI works on your phone: check why a job failed without reaching for a laptop. Tap a run and its log fills the screen, the back arrow takes you to the list. On narrow windows the sidebar tucks into a menu, and up to 1600px wide you can fold the sidebar and run list away to give the log more room.
  • The Web UI and the TUI show live CPU and memory use for running tasks and services, and each run records its peak memory and CPU time. Live use is also exported as the runwisp_task_cpu_percent and runwisp_task_memory_bytes metrics.
  • The Docker image writes a starter runwisp.toml on first start when you mount an empty config directory at /etc/runwisp.
  • runwisp start, stop and restart take --attach to follow the targets’ logs right after, like runwisp logs -f.

Changed

  • runwisp reload now applies notifiers, routes, [notify], [storage], and [daemon] settings including timezone, and lists them on ~ setting lines. Only a few [daemon] keys, such as the TLS and metrics settings, still need runwisp restart.
  • Single-instance services show their run history beside the log like every other task, and Stop Service is now Stop.
  • The update check also reports how RunWisp was installed (docker, npm, npx, script or other), nothing else is added. check_updates = false still turns it off.
  • A plain-HTTP request to the HTTPS port is redirected to the https:// URL instead of getting “Client sent an HTTP request to an HTTPS server.”.
  • Quitting the runwisp demo TUI shuts the demo daemon down instead of asking whether to keep it running. Use runwisp demo --no-tui to keep it in the background.
  • runwisp import maps systemd Restart= and supervisord autorestart onto the restart key (on-failure and unexpected become on_failure, no becomes never), and reads no, off and 0 as supervisord’s “don’t restart”. Restart=on-success becomes never, since it never restarts after a failure.
  • The “update available” release-notes link in the Web UI and the TUI opens runwisp.com/releases.
  • When runwisp.toml has unapplied edits, runwisp status now points at runwisp reload instead of runwisp restart.

Fixed

  • The Web UI opens the login prompt when your session expires while a page is open, so run lists and notifications don’t stop updating.
  • The Web UI keeps a single live stream when a page subscribes during a reconnect.
  • Log search paging moves past a hit on the first line of a log instead of returning it again.
  • Line counts and tail views stay correct for running or killed runs whose log has a line of 64 KiB or more.
  • A notification that groups repeated failures now links to the latest run.
  • Copying a run ID in the Web UI works when the dashboard is served over plain HTTP.
  • A search hit opened in a running run’s log is scrolled to once, so new output doesn’t pull the view back.
  • runwisp run exits 1 when a run is marked failed but the process exited 0 or never started, such as a failures output pattern match, a timeout the task handled, or a skipped run.
  • runwisp import reads supervisord configs the way supervisord does (inline ; and # comments are dropped, and a comment or blank line doesn’t end a multi-line value), keeps matched quote pairs in crontab environment values, writes control characters in commands as valid TOML, and reads systemd ExecStart arguments the way systemd does (quotes, escapes, $$, %%), quoting them so the shell passes them on unchanged while $VAR and ${VAR} still expand.
  • runwisp import systemd leaves out an EnvironmentFile=-path that doesn’t exist yet (with a note), no longer turns TimeoutStopSec=0 into an immediate kill, uses the last of TimeoutSec= and TimeoutStopSec=, and no longer lets a comment ending in \ hide the next line.
  • The systemd unit written by runwisp service install keeps a literal $ in the binary, config or data path.
  • Two daemons can no longer end up sharing a data dir when one starts as another stops.
  • Failures held back by notification coalescing are sent as a summary when the daemon stops, instead of being dropped.
  • RunWisp starts when the data dir belongs to another user (a Kubernetes fsGroup volume, a group-writable bind mount) and warns that its permissions are looser than 0700.
  • runwisp stop and restart recognize a running daemon by its PID file lock, so a recycled PID or a renamed binary is no longer mistaken for the daemon.
  • Schedules that can never fire, such as 0 0 30 2 *, and @every intervals under one second are now rejected by runwisp validate and on load or reload. Day-of-week ranges like sun-7 are accepted.
  • On shutdown the daemon now waits until tasks that ignore the stop signal have been killed before it exits, so no child process is left running.
  • A service reloaded into a plain task and back to a service is started again.
  • A run refused for low disk space, or killed by a signal, now says so in its log.
  • Overlapping runs of a compose task in run mode each get their own container, and one no longer removes the other’s.
  • A run no longer fails to start when a cleanup pass removes its log directory at the same moment.
  • A queue-policy task that a reload removed and re-added while a run was still going could leave its queued runs waiting forever.

Security

  • HTTP task logs hide URL credentials and query values, and a redirect to another host no longer carries credential headers or the original URL along. SSRF checks also reject deprecated IPv4-compatible IPv6 addresses.
  • Browser CSRF checks refuse a plain http page on the same host when the daemon is reached over HTTPS, and a non-Bearer Authorization header (such as a proxy’s Basic auth) no longer exempts a request from them.
  • When secret values overlap in run output, such as one being a prefix of another, each is now fully masked.
  • Slack notifications escape &, < and > and keep task output inside its code block, so output can’t produce @channel mentions or links.
All releases