Changelog
v0.5.0 - 2026-10-21
Breaking
- Default config path changed from
/etc/reconD/config.yamlto/etc/recond/config.yaml. - Default deployments state path changed from
/var/lib/reconD/deployments_state.jsonto/var/lib/recond/deployments_state.json.
Existing installations that rely on the default paths must migrate before running this version:
- If the old default config path was used, the new version finds no
/etc/recond/config.yaml, exits withload config error, and is restarted by systemd every 5 seconds. - If only
-configwas passed, the new version starts with an empty state file. Without the previous state, reconD has no rollback target and no recorded terminal failures, so a digest that was previously marked as failed can be deployed again.
Stop and disable any reconD service currently running prior to this version, for example a hand-written reconD.service, so it does not start next to the packaged recond.service on the next boot. Two agents would reconcile the same workloads with separate state files. Then move the files:
sudo systemctl disable --now reconD # the unit name you used before, if any
sudo mkdir -p /etc/recond /var/lib/recond
sudo mv /etc/reconD/config.yaml /etc/recond/config.yaml
sudo mv /var/lib/reconD/deployments_state.json /var/lib/recond/deployments_state.jsonTo keep the old locations instead, override the packaged unit's command with sudo systemctl edit recond. The empty ExecStart= clears the packaged command before setting the new one:
[Service]
ExecStart=
ExecStart=/usr/bin/recond -config /etc/reconD/config.yaml -state /var/lib/reconD/deployments_state.jsonWith this override, package installs and upgrades still print setup directions, because /etc/recond/config.yaml does not exist.
Added
- Official
.deband.rpmpackages foramd64/x86_64andarm64/aarch64, published on GitHub Releases withchecksums.txt. Tags with a prerelease suffix, such asv0.5.0-rc.1, are published as prereleases. - Packages install the
recondbinary to/usr/bin/recond, arecond.servicesystemd unit,/etc/recond/config.yaml.example, and/var/lib/recond(mode0750). -versionflag that prints the build version, commit, and date.- The packaged service runs
deploy_commandfrom/withHOME=/root. Use absolute paths or start the command withcd, for examplecd /opt/my-app && make redeploy-app. - Package installs, upgrades, and reinstalls print setup directions until
/etc/recond/config.yamlexists. - Packages ship the MIT license as
/usr/share/doc/recond/copyright(.deb) and/usr/share/licenses/recond/LICENSE(.rpm). apt purge reconddeletes/etc/recondand/var/lib/recond, including config and deployment state.apt remove,dnf remove, andzypper removekeep them.- CI lints the package scripts, builds snapshot packages on every pull request, and tests the service lifecycle:
.debinstall, run, reinstall, remove, reinstall, purge, and upgrade of a running service on a systemd host, and.rpminstall, run, reinstall, erase, and upgrade in Fedora containers with and without a running systemd. Upgrades start from the latest released package, or from av0.0.0snapshot before the first packaged release. - Releases run the full CI workflow, including the package lifecycle tests, before publishing.
v0.4.2 - 2026-10-12
Added
- Added
deployment_retryconfiguration for bounded forward deployment and rollback attempts. - Added top-level
deployment_retrydefaults that apply to every workload. - Added workload-level
deployment_retryoverrides; workload settings override only the fields they explicitly set. - Added exponential retry backoff with jitter for deployment strategy, deploy command, health-check, and rollback failures.
- Added persisted terminal failure state for deployment digests that exhaust forward retry attempts, preventing repeated automatic deployment loops.
Changed
- Forward deployment attempts default to
1, preserving previous single-attempt behavior unless retry settings are configured. - Rollback attempts default to
1, with retry delay defaults of1sinitial interval,30smax interval, and multiplier2. - Rollback now starts only after forward deployment attempts are exhausted.
- Reconciliation now skips automatic deployment when a terminal failure matches the desired manifest digest.
- Reconciliation allows deployment of a newer desired manifest digest when an existing terminal failure belongs to an older digest.
- Successful forward deployment commits now clear terminal failure state for the workload.
- Successful rollback after forward retry exhaustion now persists terminal failure for the failed desired digest, preventing the next reconciliation cycle from retrying the same known-bad digest automatically.
- Deployment state types were clarified:
DeploymentStateis the outer per-workload record, whileDeploymentSnapshotis the current or previous deployed snapshot. - Slack success notifications now receive workload name separately from the deployment snapshot.
Fixed
- Context cancellation during deployment retry backoff and rollback retry backoff now stops retries promptly.
- Unexpected previous-state load errors now abort deployment instead of attempting rollback with an empty previous snapshot.
- Unexpected terminal-failure load errors now abort reconciliation instead of treating terminal failure state as absent.
- Terminal failure records for deployments with no previous state now record zero rollback attempts because no rollback was attempted.
- Rollback commits no longer clear terminal failure state, so a failed desired digest remains blocked even after rollback restores the previous known-good deployment.
- Commit failures during deployment or rollback now surface as deployment errors instead of being reported as successful deployments.
- Backoff delay calculation now clamps safely before duration conversion and caps jittered delays to the configured max interval.
Upgrade Notes
- Existing central state files remain compatible with the new state layout. Terminal failure state is stored as an optional
terminal_failurefield and is omitted when absent. DeploymentSnapshotandTerminalFailureStateno longer carryworkload_name; the outerDeploymentState.workload_nameidentifies the workload.
v0.4.1 - 2026-10-08
Changed
- Deployment state is now managed centrally in one deployments state file for all workloads, keyed by workload name.
- Added the
-stateflag to configure the deployments state file path. It defaults to/var/lib/reconD/deployments_state.json. - Workload-level
state_diris no longer required and is no longer used. - Duplicate workload names are now rejected, since workload name is the deployment state key.
- Missing state errors now distinguish between a missing state file and missing deployment state.
Upgrade Notes
- This is not treated as a breaking config change: existing YAML files that still include
state_dircontinue to load, butstate_diris ignored. - Existing per-workload
deployed.jsonandprevious.jsonfiles are not automatically migrated into the new central state file. Operators should migrate state manually or expect the first run with the new state file to behave like no deployment state has been recorded yet.
v0.4.0 - 2026-10-08
Breaking Changes
Logging configuration now lives in the config file under top-level
logsettings instead ofLOG_FORMATandLOG_LEVELenvironment variables.yamllog: format: text level: debug
Changed
logger.Setupnow receivesconfig.Log, keeping logger configuration with the rest of the application config.
v0.3.0 - 2026-10-08
Breaking Changes
Workload
environmenthas been removed from config, deployment metadata, deployment state, and deploy command environment variables.Use optional
release_prefixto scope GitHub release metadata lookup when a repository publishes multiple deployable artifact streams.yamlworkloads: - name: my-app release_prefix: my-app-prod
Changed
- Notifications now identify deployments by workload name instead of environment.
- When
release_prefixis empty, GitHub release lookup considers all releases newest-first and deploys the first release with validdeployment-metadata.json.
v0.2.0 - 2026-10-08
Breaking Changes
Configuration files must now be YAML and use a
.yamlor.ymlextension.JSON configuration files are no longer supported.
Config files must define a top-level
workloadslist, even for a single workload.yamlworkloads: - name: my-app environment: prodSingle-workload shorthand YAML is no longer supported.
yaml# No longer supported: name: my-app environment: prod
Changed
- Updated config loading, tests, and README examples for YAML-only configuration.