The shared setProperty / unsetProperty helpers in tasks/properties.go (line 66 and line 109) carry // todo: validate that the value isn't already set/unset comments. They currently always exec dokku <plugin>:set and unconditionally report Changed: true on success. As a result, every property task built on executeProperty (builder_property, git_property, network_property, nginx_property, scheduler_property) is non-idempotent.
Implement idempotency in the shared helper:
- Query current value via
dokku <plugin>:report <app> --<plugin>-<property> (per-app) or dokku <plugin>:report --<plugin>-global-<property> (global). Info-flag form is required because --format json is unsupported by git:report / nginx:report, and rejected entirely for any --global query (see dokku/dokku follow-ups).
- On
present: if current value matches desired, return Changed: false, State: "present" without exec.
- On
absent: if current value is empty, return Changed: false, State: "absent" without exec.
- On unknown property (stderr matches
Invalid flag passed, valid flags:): warn via log.Printf and fall through to exec.
- On any other report error (dokku missing, app missing,
not deployed, transient failure): silent fallthrough to exec — preserves today's behavior.
- The set/unset exec error path is unchanged:
TaskOutputErrorFromExec continues to wrap stderr/err into the returned state.
Tests should cover:
- Repeated
present of the same value reports Changed: false.
- Repeated
absent reports Changed: false.
- Unknown property triggers the warning and still falls through to exec.
- Existing validation tests continue to pass.
Spun off from #128 to keep that PR scoped to mirroring the existing property-task pattern.
The shared
setProperty/unsetPropertyhelpers intasks/properties.go(line 66 and line 109) carry// todo: validate that the value isn't already set/unsetcomments. They currently always execdokku <plugin>:setand unconditionally reportChanged: trueon success. As a result, every property task built onexecuteProperty(builder_property,git_property,network_property,nginx_property,scheduler_property) is non-idempotent.Implement idempotency in the shared helper:
dokku <plugin>:report <app> --<plugin>-<property>(per-app) ordokku <plugin>:report --<plugin>-global-<property>(global). Info-flag form is required because--format jsonis unsupported bygit:report/nginx:report, and rejected entirely for any--globalquery (see dokku/dokku follow-ups).present: if current value matches desired, returnChanged: false, State: "present"without exec.absent: if current value is empty, returnChanged: false, State: "absent"without exec.Invalid flag passed, valid flags:): warn vialog.Printfand fall through to exec.not deployed, transient failure): silent fallthrough to exec — preserves today's behavior.TaskOutputErrorFromExeccontinues to wrap stderr/err into the returned state.Tests should cover:
presentof the same value reportsChanged: false.absentreportsChanged: false.Spun off from #128 to keep that PR scoped to mirroring the existing property-task pattern.