From 4001f318a68783ebeefbf3de5301cc993ecba278 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 13 May 2026 12:37:14 -0400 Subject: [PATCH] fix: support --global on cron:set `cron:set --global` wrote the property but emitted `unknown flag: --global` because the post-set `scheduler-cron-write` trigger received `--global` as the appName arg, which pflag rejected before reaching the trigger body. The trigger args now omit appName for global writes, and the `scheduler-k3s` cron-write trigger short-circuits when called without an app since per-app reconciliation requires a real app name. The docker-local trigger already regenerates the global crontab from all apps so global `mailfrom`/`mailto` are picked up without any further changes. --- docs/processes/scheduled-cron-tasks.md | 2 +- plugins/cron/subcommands.go | 6 ++- plugins/scheduler-k3s/triggers.go | 4 ++ tests/unit/cron.bats | 74 ++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/docs/processes/scheduled-cron-tasks.md b/docs/processes/scheduled-cron-tasks.md index e9473312d..5bb9b6b3d 100644 --- a/docs/processes/scheduled-cron-tasks.md +++ b/docs/processes/scheduled-cron-tasks.md @@ -68,7 +68,7 @@ The `cron` plugin provides a number of settings that can be used to managed depl | Name | Description | Level | Global Default | |-----------------------|----------------------------------------------------------------|-------------|----------------| | `mailfrom` | Sets the `MAILFROM` variable in a cron file for cron reporting | Global-only | empty string | -| `maintenance` | Whether to have cron running for the app or not. | App-only | `false` | +| `maintenance` | Whether to have cron running for the app or not. | App and Global | `false` | | `mailto` | Sets the `MAILTO` variable in a cron file for cron reporting | Global-only | empty string | All settings can be set via the `cron:set` command. Using `maintenance` as an example: diff --git a/plugins/cron/subcommands.go b/plugins/cron/subcommands.go index 8bc86677f..e3d054545 100644 --- a/plugins/cron/subcommands.go +++ b/plugins/cron/subcommands.go @@ -192,9 +192,13 @@ func CommandSet(appName string, property string, value string) error { common.CommandPropertySet("cron", appName, property, value, validProperties, globalProperties) scheduler := common.GetAppScheduler(appName) + triggerArgs := []string{scheduler, appName} + if appName == "--global" { + triggerArgs = []string{scheduler} + } _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{ Trigger: "scheduler-cron-write", - Args: []string{scheduler, appName}, + Args: triggerArgs, StreamStdio: true, }) return err diff --git a/plugins/scheduler-k3s/triggers.go b/plugins/scheduler-k3s/triggers.go index d1e01f360..cf21f33f2 100644 --- a/plugins/scheduler-k3s/triggers.go +++ b/plugins/scheduler-k3s/triggers.go @@ -255,6 +255,10 @@ func TriggerSchedulerCronWrite(scheduler string, appName string) error { return nil } + if appName == "" { + return nil + } + cronTasks, err := cron.FetchCronTasks(cron.FetchCronTasksInput{AppName: appName}) if err != nil { return fmt.Errorf("Error fetching cron tasks: %w", err) diff --git a/tests/unit/cron.bats b/tests/unit/cron.bats index c579d4496..ab7cebe88 100644 --- a/tests/unit/cron.bats +++ b/tests/unit/cron.bats @@ -120,6 +120,80 @@ teardown() { assert_success } +@test "(cron:set) --global mailto" { + run /bin/bash -c "dokku cron:set --global mailto admin@example.com" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_not_contains "unknown flag" + + run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-mailto\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "admin@example.com" + + run /bin/bash -c "dokku cron:set --global mailto" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_not_contains "unknown flag" + + run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-mailto\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" +} + +@test "(cron:set) --global mailfrom" { + run /bin/bash -c "dokku cron:set --global mailfrom dokku@example.com" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_not_contains "unknown flag" + + run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-mailfrom\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "dokku@example.com" + + run /bin/bash -c "dokku cron:set --global mailfrom" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_not_contains "unknown flag" +} + +@test "(cron:set) --global maintenance" { + run /bin/bash -c "dokku cron:set --global maintenance true" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_not_contains "unknown flag" + + run /bin/bash -c "dokku cron:report --global --format json | jq -r '.\"cron-global-maintenance\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "true" + + run /bin/bash -c "dokku cron:set --global maintenance" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_not_contains "unknown flag" +} + +@test "(cron:set) --global rejects task maintenance properties" { + run /bin/bash -c "dokku cron:set --global maintenance.fakeid true" + echo "output: $output" + echo "status: $status" + assert_failure + assert_output_contains "Task maintenance properties cannot be set globally" +} + @test "(cron) create [multiple]" { run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP template_cron_file_valid_multiple echo "output: $output"